diff options
60 files changed, 3605 insertions, 1042 deletions
diff --git a/babeld/babel_main.c b/babeld/babel_main.c index 529c3f295..0b3e549f3 100644 --- a/babeld/babel_main.c +++ b/babeld/babel_main.c @@ -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); diff --git a/babeld/babel_zebra.c b/babeld/babel_zebra.c index 75a1e6a84..f584e0396 100644 --- a/babeld/babel_zebra.c +++ b/babeld/babel_zebra.c @@ -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); diff --git a/babeld/babeld.c b/babeld/babeld.c index 1ae3f042c..334f64c31 100644 --- a/babeld/babeld.c +++ b/babeld/babeld.c @@ -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++; diff --git a/bgpd/bgp_main.c b/bgpd/bgp_main.c index 62fcb64d6..234f17d1f 100644 --- a/bgpd/bgp_main.c +++ b/bgpd/bgp_main.c @@ -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. */ diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 24a46c04d..cb10cf2e6 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -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) diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h index 56d72c4e7..f452ea254 100644 --- a/bgpd/bgp_route.h +++ b/bgpd/bgp_route.h @@ -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 *, diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c index 2a88f0f08..2e68f31ab 100644 --- a/bgpd/bgp_routemap.c +++ b/bgpd/bgp_routemap.c @@ -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); - - if (bgp->redist[afi][i] && route_update) - { - if (BGP_DEBUG (zebra, ZEBRA)) - zlog_debug("Processing route_map %s update on " - "redistributed routes", rmap_name); - - bgp_redistribute_resend (bgp, afi, i); - } + struct list *red_list; + struct listnode *node; + struct bgp_redist *red; + + red_list = bgp->redist[afi][i]; + if (!red_list) + continue; + + 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); + } + } } } diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 92c402db5..3c625755c 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -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); - - /* "redistribute" configuration. */ - vty_out (vty, " redistribute %s", zebra_route_string(i)); - - if (bgp->redist_metric_flag[afi][i]) - vty_out (vty, " metric %u", bgp->redist_metric[afi][i]); + struct list *red_list; + struct listnode *node; + struct bgp_redist *red; - if (bgp->rmap[afi][i].name) - vty_out (vty, " route-map %s", bgp->rmap[afi][i].name); + red_list = bgp->redist[afi][i]; + if (!red_list) + continue; - vty_out (vty, "%s", VTY_NEWLINE); + 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); + + /* "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); diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index d2787ec82..386de45ed 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -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; diff --git a/bgpd/bgp_zebra.h b/bgpd/bgp_zebra.h index 334e3af1d..be94c5a01 100644 --- a/bgpd/bgp_zebra.h +++ b/bgpd/bgp_zebra.h @@ -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 *); diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 7df12326a..8ec27e338 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -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)) { diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 14852293d..94540749b 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -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 */ diff --git a/isisd/isis_main.c b/isisd/isis_main.c index 283b7eaae..f87314859 100644 --- a/isisd/isis_main.c +++ b/isisd/isis_main.c @@ -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 */ diff --git a/isisd/isis_zebra.c b/isisd/isis_zebra.c index 2df746291..dfedc624c 100644 --- a/isisd/isis_zebra.c +++ b/isisd/isis_zebra.c @@ -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; @@ -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; @@ -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); diff --git a/lib/routemap.c b/lib/routemap.c index b884fed2a..40ba87da4 100644 --- a/lib/routemap.c +++ b/lib/routemap.c @@ -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) { diff --git a/lib/zclient.c b/lib/zclient.c index 24962bac3..f2f910f6b 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -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); } diff --git a/lib/zclient.h b/lib/zclient.h index e1bb2000c..3c214d278 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -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; diff --git a/ospf6d/ospf6_main.c b/ospf6d/ospf6_main.c index 8272d4733..75e409357 100644 --- a/ospf6d/ospf6_main.c +++ b/ospf6d/ospf6_main.c @@ -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); diff --git a/ospf6d/ospf6_zebra.c b/ospf6d/ospf6_zebra.c index 04a1fd648..78dd0f6d2 100644 --- a/ospf6d/ospf6_zebra.c +++ b/ospf6d/ospf6_zebra.c @@ -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; diff --git a/ospf6d/ospf6_zebra.h b/ospf6d/ospf6_zebra.h index 753b8edc9..b7a609d3a 100644 --- a/ospf6d/ospf6_zebra.h +++ b/ospf6d/ospf6_zebra.h @@ -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); diff --git a/ospfd/ospf_asbr.c b/ospfd/ospf_asbr.c index f4140b858..5eb97d8f6 100644 --- a/ospfd/ospf_asbr.c +++ b/ospfd/ospf_asbr.c @@ -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)) { diff --git a/ospfd/ospf_asbr.h b/ospfd/ospf_asbr.h index bb773c979..ade671013 100644 --- a/ospfd/ospf_asbr.h +++ b/ospfd/ospf_asbr.h @@ -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 *); diff --git a/ospfd/ospf_dump.c b/ospfd/ospf_dump.c index de62e0b7f..af5cbf534 100644 --- a/ospfd/ospf_dump.c +++ b/ospfd/ospf_dump.c @@ -755,60 +755,51 @@ ospf_packet_dump (struct stream *s) /* - [no] debug ospf packet (hello|dd|ls-request|ls-update|ls-ack|all) + [no] debug ospf [<1-65535>] packet (hello|dd|ls-request|ls-update|ls-ack|all) [send|recv [detail]] */ -DEFUN (debug_ospf_packet, - debug_ospf_packet_all_cmd, - "debug ospf packet (hello|dd|ls-request|ls-update|ls-ack|all)", - DEBUG_STR - OSPF_STR - "OSPF packets\n" - "OSPF Hello\n" - "OSPF Database Description\n" - "OSPF Link State Request\n" - "OSPF Link State Update\n" - "OSPF Link State Acknowledgment\n" - "OSPF all packets\n") +static int +debug_ospf_packet_common (struct vty *vty, int arg_base, int argc, + const char **argv) { int type = 0; int flag = 0; int i; - assert (argc > 0); + assert (argc > arg_base + 0); /* Check packet type. */ - if (strncmp (argv[0], "h", 1) == 0) + if (strncmp (argv[arg_base + 0], "h", 1) == 0) type = OSPF_DEBUG_HELLO; - else if (strncmp (argv[0], "d", 1) == 0) + else if (strncmp (argv[arg_base + 0], "d", 1) == 0) type = OSPF_DEBUG_DB_DESC; - else if (strncmp (argv[0], "ls-r", 4) == 0) + else if (strncmp (argv[arg_base + 0], "ls-r", 4) == 0) type = OSPF_DEBUG_LS_REQ; - else if (strncmp (argv[0], "ls-u", 4) == 0) + else if (strncmp (argv[arg_base + 0], "ls-u", 4) == 0) type = OSPF_DEBUG_LS_UPD; - else if (strncmp (argv[0], "ls-a", 4) == 0) + else if (strncmp (argv[arg_base + 0], "ls-a", 4) == 0) type = OSPF_DEBUG_LS_ACK; - else if (strncmp (argv[0], "a", 1) == 0) + else if (strncmp (argv[arg_base + 0], "a", 1) == 0) type = OSPF_DEBUG_ALL; /* Default, both send and recv. */ - if (argc == 1) + if (argc == arg_base + 1) flag = OSPF_DEBUG_SEND | OSPF_DEBUG_RECV; /* send or recv. */ - if (argc >= 2) + if (argc >= arg_base + 2) { - if (strncmp (argv[1], "s", 1) == 0) + if (strncmp (argv[arg_base + 1], "s", 1) == 0) flag = OSPF_DEBUG_SEND; - else if (strncmp (argv[1], "r", 1) == 0) + else if (strncmp (argv[arg_base + 1], "r", 1) == 0) flag = OSPF_DEBUG_RECV; - else if (strncmp (argv[1], "d", 1) == 0) + else if (strncmp (argv[arg_base + 1], "d", 1) == 0) flag = OSPF_DEBUG_SEND | OSPF_DEBUG_RECV | OSPF_DEBUG_DETAIL; } /* detail. */ - if (argc == 3) - if (strncmp (argv[2], "d", 1) == 0) + if (argc == arg_base + 3) + if (strncmp (argv[arg_base + 2], "d", 1) == 0) flag |= OSPF_DEBUG_DETAIL; for (i = 0; i < 5; i++) @@ -823,6 +814,22 @@ DEFUN (debug_ospf_packet, return CMD_SUCCESS; } +DEFUN (debug_ospf_packet, + debug_ospf_packet_all_cmd, + "debug ospf packet (hello|dd|ls-request|ls-update|ls-ack|all)", + DEBUG_STR + OSPF_STR + "OSPF packets\n" + "OSPF Hello\n" + "OSPF Database Description\n" + "OSPF Link State Request\n" + "OSPF Link State Update\n" + "OSPF Link State Acknowledgment\n" + "OSPF all packets\n") +{ + return (debug_ospf_packet_common(vty, 0, argc, argv)); +} + ALIAS (debug_ospf_packet, debug_ospf_packet_send_recv_cmd, "debug ospf packet (hello|dd|ls-request|ls-update|ls-ack|all) (send|recv|detail)", @@ -855,13 +862,12 @@ ALIAS (debug_ospf_packet, "Packet received\n" "Detail Information\n") - -DEFUN (no_debug_ospf_packet, - no_debug_ospf_packet_all_cmd, - "no debug ospf packet (hello|dd|ls-request|ls-update|ls-ack|all)", - NO_STR +DEFUN (debug_ospf_instance_packet, + debug_ospf_instance_packet_all_cmd, + "debug ospf <1-65535> packet (hello|dd|ls-request|ls-update|ls-ack|all)", DEBUG_STR OSPF_STR + "Instance ID\n" "OSPF packets\n" "OSPF Hello\n" "OSPF Database Description\n" @@ -870,44 +876,91 @@ DEFUN (no_debug_ospf_packet, "OSPF Link State Acknowledgment\n" "OSPF all packets\n") { + u_short instance = 0; + + VTY_GET_INTEGER ("Instance", instance, argv[0]); + if (!ospf_lookup_instance (instance)) + return CMD_SUCCESS; + + return (debug_ospf_packet_common(vty, 1, argc, argv)); +} + +ALIAS (debug_ospf_instance_packet, + debug_ospf_instance_packet_send_recv_cmd, + "debug ospf <1-65535> packet (hello|dd|ls-request|ls-update|ls-ack|all) (send|recv|detail)", + "Debugging functions\n" + "OSPF information\n" + "Instance ID\n" + "OSPF packets\n" + "OSPF Hello\n" + "OSPF Database Description\n" + "OSPF Link State Request\n" + "OSPF Link State Update\n" + "OSPF Link State Acknowledgment\n" + "OSPF all packets\n" + "Packet sent\n" + "Packet received\n" + "Detail information\n") + +ALIAS (debug_ospf_instance_packet, + debug_ospf_instance_packet_send_recv_detail_cmd, + "debug ospf <1-65535> packet (hello|dd|ls-request|ls-update|ls-ack|all) (send|recv) (detail|)", + "Debugging functions\n" + "OSPF information\n" + "Instance ID\n" + "OSPF packets\n" + "OSPF Hello\n" + "OSPF Database Description\n" + "OSPF Link State Request\n" + "OSPF Link State Update\n" + "OSPF Link State Acknowledgment\n" + "OSPF all packets\n" + "Packet sent\n" + "Packet received\n" + "Detail Information\n") + +static int +no_debug_ospf_packet_common (struct vty *vty, int arg_base, int argc, + const char **argv) +{ int type = 0; int flag = 0; int i; - assert (argc > 0); + assert (argc > arg_base + 0); /* Check packet type. */ - if (strncmp (argv[0], "h", 1) == 0) + if (strncmp (argv[arg_base + 0], "h", 1) == 0) type = OSPF_DEBUG_HELLO; - else if (strncmp (argv[0], "d", 1) == 0) + else if (strncmp (argv[arg_base + 0], "d", 1) == 0) type = OSPF_DEBUG_DB_DESC; - else if (strncmp (argv[0], "ls-r", 4) == 0) + else if (strncmp (argv[arg_base + 0], "ls-r", 4) == 0) type = OSPF_DEBUG_LS_REQ; - else if (strncmp (argv[0], "ls-u", 4) == 0) + else if (strncmp (argv[arg_base + 0], "ls-u", 4) == 0) type = OSPF_DEBUG_LS_UPD; - else if (strncmp (argv[0], "ls-a", 4) == 0) + else if (strncmp (argv[arg_base + 0], "ls-a", 4) == 0) type = OSPF_DEBUG_LS_ACK; - else if (strncmp (argv[0], "a", 1) == 0) + else if (strncmp (argv[arg_base + 0], "a", 1) == 0) type = OSPF_DEBUG_ALL; /* Default, both send and recv. */ - if (argc == 1) + if (argc == arg_base + 1) flag = OSPF_DEBUG_SEND | OSPF_DEBUG_RECV | OSPF_DEBUG_DETAIL ; /* send or recv. */ - if (argc == 2) + if (argc == arg_base + 2) { - if (strncmp (argv[1], "s", 1) == 0) + if (strncmp (argv[arg_base + 1], "s", 1) == 0) flag = OSPF_DEBUG_SEND | OSPF_DEBUG_DETAIL; - else if (strncmp (argv[1], "r", 1) == 0) + else if (strncmp (argv[arg_base + 1], "r", 1) == 0) flag = OSPF_DEBUG_RECV | OSPF_DEBUG_DETAIL; - else if (strncmp (argv[1], "d", 1) == 0) + else if (strncmp (argv[arg_base + 1], "d", 1) == 0) flag = OSPF_DEBUG_DETAIL; } /* detail. */ - if (argc == 3) - if (strncmp (argv[2], "d", 1) == 0) + if (argc == arg_base + 3) + if (strncmp (argv[arg_base + 2], "d", 1) == 0) flag = OSPF_DEBUG_DETAIL; for (i = 0; i < 5; i++) @@ -929,6 +982,23 @@ DEFUN (no_debug_ospf_packet, return CMD_SUCCESS; } +DEFUN (no_debug_ospf_packet, + no_debug_ospf_packet_all_cmd, + "no debug ospf packet (hello|dd|ls-request|ls-update|ls-ack|all)", + NO_STR + DEBUG_STR + OSPF_STR + "OSPF packets\n" + "OSPF Hello\n" + "OSPF Database Description\n" + "OSPF Link State Request\n" + "OSPF Link State Update\n" + "OSPF Link State Acknowledgment\n" + "OSPF all packets\n") +{ + return no_debug_ospf_packet_common(vty, 0, argc, argv); +} + ALIAS (no_debug_ospf_packet, no_debug_ospf_packet_send_recv_cmd, "no debug ospf packet (hello|dd|ls-request|ls-update|ls-ack|all) (send|recv|detail)", @@ -963,25 +1033,81 @@ ALIAS (no_debug_ospf_packet, "Packet received\n" "Detail Information\n") - -DEFUN (debug_ospf_ism, - debug_ospf_ism_cmd, - "debug ospf ism", +DEFUN (no_debug_ospf_instance_packet, + no_debug_ospf_instance_packet_all_cmd, + "no debug ospf <1-65535> packet (hello|dd|ls-request|ls-update|ls-ack|all)", + NO_STR DEBUG_STR OSPF_STR - "OSPF Interface State Machine\n") + "Instance ID\n" + "OSPF packets\n" + "OSPF Hello\n" + "OSPF Database Description\n" + "OSPF Link State Request\n" + "OSPF Link State Update\n" + "OSPF Link State Acknowledgment\n" + "OSPF all packets\n") +{ + u_short instance = 0; + + VTY_GET_INTEGER ("Instance", instance, argv[0]); + if (!ospf_lookup_instance (instance)) + return CMD_SUCCESS; + + return (no_debug_ospf_packet_common(vty, 1, argc, argv)); +} + +ALIAS (no_debug_ospf_instance_packet, + no_debug_ospf_instance_packet_send_recv_cmd, + "no debug ospf <1-65535> packet (hello|dd|ls-request|ls-update|ls-ack|all) (send|recv|detail)", + NO_STR + "Debugging functions\n" + "OSPF information\n" + "Instance ID\n" + "OSPF packets\n" + "OSPF Hello\n" + "OSPF Database Description\n" + "OSPF Link State Request\n" + "OSPF Link State Update\n" + "OSPF Link State Acknowledgment\n" + "OSPF all packets\n" + "Packet sent\n" + "Packet received\n" + "Detail Information\n") + +ALIAS (no_debug_ospf_instance_packet, + no_debug_ospf_instance_packet_send_recv_detail_cmd, + "no debug ospf <1-65535> packet (hello|dd|ls-request|ls-update|ls-ack|all) (send|recv) (detail|)", + NO_STR + "Debugging functions\n" + "OSPF information\n" + "Instance ID\n" + "OSPF packets\n" + "OSPF Hello\n" + "OSPF Database Description\n" + "OSPF Link State Request\n" + "OSPF Link State Update\n" + "OSPF Link State Acknowledgment\n" + "OSPF all packets\n" + "Packet sent\n" + "Packet received\n" + "Detail Information\n") + + +static int +debug_ospf_ism_common (struct vty *vty, int arg_base, int argc, const char **argv) { if (vty->node == CONFIG_NODE) { - if (argc == 0) + if (argc == arg_base + 0) DEBUG_ON (ism, ISM); - else if (argc == 1) + else if (argc == arg_base + 1) { - if (strncmp (argv[0], "s", 1) == 0) + if (strncmp (argv[arg_base + 0], "s", 1) == 0) DEBUG_ON (ism, ISM_STATUS); - else if (strncmp (argv[0], "e", 1) == 0) + else if (strncmp (argv[arg_base + 0], "e", 1) == 0) DEBUG_ON (ism, ISM_EVENTS); - else if (strncmp (argv[0], "t", 1) == 0) + else if (strncmp (argv[arg_base + 0], "t", 1) == 0) DEBUG_ON (ism, ISM_TIMERS); } @@ -989,21 +1115,31 @@ DEFUN (debug_ospf_ism, } /* ENABLE_NODE. */ - if (argc == 0) + if (argc == arg_base + 0) TERM_DEBUG_ON (ism, ISM); - else if (argc == 1) + else if (argc == arg_base + 1) { - if (strncmp (argv[0], "s", 1) == 0) + if (strncmp (argv[arg_base + 0], "s", 1) == 0) TERM_DEBUG_ON (ism, ISM_STATUS); - else if (strncmp (argv[0], "e", 1) == 0) + else if (strncmp (argv[arg_base + 0], "e", 1) == 0) TERM_DEBUG_ON (ism, ISM_EVENTS); - else if (strncmp (argv[0], "t", 1) == 0) + else if (strncmp (argv[arg_base + 0], "t", 1) == 0) TERM_DEBUG_ON (ism, ISM_TIMERS); } return CMD_SUCCESS; } +DEFUN (debug_ospf_ism, + debug_ospf_ism_cmd, + "debug ospf ism", + DEBUG_STR + OSPF_STR + "OSPF Interface State Machine\n") +{ + return debug_ospf_ism_common(vty, 0, argc, argv); +} + ALIAS (debug_ospf_ism, debug_ospf_ism_sub_cmd, "debug ospf ism (status|events|timers)", @@ -1014,46 +1150,81 @@ ALIAS (debug_ospf_ism, "ISM Event Information\n" "ISM TImer Information\n") -DEFUN (no_debug_ospf_ism, - no_debug_ospf_ism_cmd, - "no debug ospf ism", - NO_STR +DEFUN (debug_ospf_instance_ism, + debug_ospf_instance_ism_cmd, + "debug ospf <1-65535> ism", DEBUG_STR OSPF_STR - "OSPF Interface State Machine") + "Instance ID\n" + "OSPF Interface State Machine\n") +{ + u_short instance = 0; + + VTY_GET_INTEGER ("Instance", instance, argv[0]); + if (!ospf_lookup_instance (instance)) + return CMD_SUCCESS; + + return debug_ospf_ism_common(vty, 1, argc, argv); +} + +ALIAS (debug_ospf_instance_ism, + debug_ospf_instance_ism_sub_cmd, + "debug ospf <1-65535> ism (status|events|timers)", + DEBUG_STR + OSPF_STR + "Instance ID\n" + "OSPF Interface State Machine\n" + "ISM Status Information\n" + "ISM Event Information\n" + "ISM TImer Information\n") + +static int +no_debug_ospf_ism_common(struct vty *vty, int arg_base, int argc, + const char **argv) { if (vty->node == CONFIG_NODE) { - if (argc == 0) + if (argc == arg_base + 0) DEBUG_OFF (ism, ISM); - else if (argc == 1) + else if (argc == arg_base + 1) { - if (strncmp (argv[0], "s", 1) == 0) + if (strncmp (argv[arg_base + 0], "s", 1) == 0) DEBUG_OFF (ism, ISM_STATUS); - else if (strncmp (argv[0], "e", 1) == 0) + else if (strncmp (argv[arg_base + 0], "e", 1) == 0) DEBUG_OFF (ism, ISM_EVENTS); - else if (strncmp (argv[0], "t", 1) == 0) + else if (strncmp (argv[arg_base + 0], "t", 1) == 0) DEBUG_OFF (ism, ISM_TIMERS); } return CMD_SUCCESS; } /* ENABLE_NODE. */ - if (argc == 0) + if (argc == arg_base + 0) TERM_DEBUG_OFF (ism, ISM); - else if (argc == 1) + else if (argc == arg_base + 1) { - if (strncmp (argv[0], "s", 1) == 0) + if (strncmp (argv[arg_base + 0], "s", 1) == 0) TERM_DEBUG_OFF (ism, ISM_STATUS); - else if (strncmp (argv[0], "e", 1) == 0) + else if (strncmp (argv[arg_base + 0], "e", 1) == 0) TERM_DEBUG_OFF (ism, ISM_EVENTS); - else if (strncmp (argv[0], "t", 1) == 0) + else if (strncmp (argv[arg_base + 0], "t", 1) == 0) TERM_DEBUG_OFF (ism, ISM_TIMERS); } return CMD_SUCCESS; } +DEFUN (no_debug_ospf_ism, + no_debug_ospf_ism_cmd, + "no debug ospf ism", + NO_STR + DEBUG_STR + OSPF_STR + "OSPF Interface State Machine") +{ + return no_debug_ospf_ism_common(vty, 0, argc, argv); +} + ALIAS (no_debug_ospf_ism, no_debug_ospf_ism_sub_cmd, "no debug ospf ism (status|events|timers)", @@ -1065,25 +1236,50 @@ ALIAS (no_debug_ospf_ism, "ISM Event Information\n" "ISM Timer Information\n") - -DEFUN (debug_ospf_nsm, - debug_ospf_nsm_cmd, - "debug ospf nsm", +DEFUN (no_debug_ospf_instance_ism, + no_debug_ospf_instance_ism_cmd, + "no debug ospf <1-65535> ism", + NO_STR DEBUG_STR OSPF_STR - "OSPF Neighbor State Machine\n") + "Instance ID\n" + "OSPF Interface State Machine") +{ + u_short instance = 0; + + VTY_GET_INTEGER ("Instance", instance, argv[0]); + if (!ospf_lookup_instance (instance)) + return CMD_SUCCESS; + + return no_debug_ospf_ism_common(vty, 1, argc, argv); +} + +ALIAS (no_debug_ospf_instance_ism, + no_debug_ospf_instance_ism_sub_cmd, + "no debug ospf <1-65535> ism (status|events|timers)", + NO_STR + "Debugging functions\n" + "OSPF information\n" + "Instance ID\n" + "OSPF Interface State Machine\n" + "ISM Status Information\n" + "ISM Event Information\n" + "ISM Timer Information\n") + +static int +debug_ospf_nsm_common (struct vty *vty, int arg_base, int argc, const char **argv) { if (vty->node == CONFIG_NODE) { - if (argc == 0) + if (argc == arg_base + 0) DEBUG_ON (nsm, NSM); - else if (argc == 1) + else if (argc == arg_base + 1) { - if (strncmp (argv[0], "s", 1) == 0) + if (strncmp (argv[arg_base + 0], "s", 1) == 0) DEBUG_ON (nsm, NSM_STATUS); - else if (strncmp (argv[0], "e", 1) == 0) + else if (strncmp (argv[arg_base + 0], "e", 1) == 0) DEBUG_ON (nsm, NSM_EVENTS); - else if (strncmp (argv[0], "t", 1) == 0) + else if (strncmp (argv[arg_base + 0], "t", 1) == 0) DEBUG_ON (nsm, NSM_TIMERS); } @@ -1091,21 +1287,31 @@ DEFUN (debug_ospf_nsm, } /* ENABLE_NODE. */ - if (argc == 0) + if (argc == arg_base + 0) TERM_DEBUG_ON (nsm, NSM); - else if (argc == 1) + else if (argc == arg_base + 1) { - if (strncmp (argv[0], "s", 1) == 0) + if (strncmp (argv[arg_base + 0], "s", 1) == 0) TERM_DEBUG_ON (nsm, NSM_STATUS); - else if (strncmp (argv[0], "e", 1) == 0) + else if (strncmp (argv[arg_base + 0], "e", 1) == 0) TERM_DEBUG_ON (nsm, NSM_EVENTS); - else if (strncmp (argv[0], "t", 1) == 0) + else if (strncmp (argv[arg_base + 0], "t", 1) == 0) TERM_DEBUG_ON (nsm, NSM_TIMERS); } return CMD_SUCCESS; } +DEFUN (debug_ospf_nsm, + debug_ospf_nsm_cmd, + "debug ospf nsm", + DEBUG_STR + OSPF_STR + "OSPF Neighbor State Machine\n") +{ + return debug_ospf_nsm_common (vty, 0, argc, argv); +} + ALIAS (debug_ospf_nsm, debug_ospf_nsm_sub_cmd, "debug ospf nsm (status|events|timers)", @@ -1116,25 +1322,48 @@ ALIAS (debug_ospf_nsm, "NSM Event Information\n" "NSM Timer Information\n") -DEFUN (no_debug_ospf_nsm, - no_debug_ospf_nsm_cmd, - "no debug ospf nsm", - NO_STR +DEFUN (debug_ospf_instance_nsm, + debug_ospf_instance_nsm_cmd, + "debug ospf <1-65535> nsm", DEBUG_STR OSPF_STR - "OSPF Neighbor State Machine") + "Instance ID\n" + "OSPF Neighbor State Machine\n") +{ + u_short instance = 0; + + VTY_GET_INTEGER ("Instance", instance, argv[0]); + if (!ospf_lookup_instance (instance)) + return CMD_SUCCESS; + + return debug_ospf_nsm_common (vty, 1, argc, argv); +} + +ALIAS (debug_ospf_instance_nsm, + debug_ospf_instance_nsm_sub_cmd, + "debug ospf <1-65535> nsm (status|events|timers)", + DEBUG_STR + OSPF_STR + "Instance ID\n" + "OSPF Neighbor State Machine\n" + "NSM Status Information\n" + "NSM Event Information\n" + "NSM Timer Information\n") + +static int +no_debug_ospf_nsm_common (struct vty *vty, int arg_base, int argc, const char **argv) { if (vty->node == CONFIG_NODE) { - if (argc == 0) + if (argc == arg_base + 0) DEBUG_OFF (nsm, NSM); - else if (argc == 1) + else if (argc == arg_base + 1) { - if (strncmp (argv[0], "s", 1) == 0) + if (strncmp (argv[arg_base + 0], "s", 1) == 0) DEBUG_OFF (nsm, NSM_STATUS); - else if (strncmp (argv[0], "e", 1) == 0) + else if (strncmp (argv[arg_base + 0], "e", 1) == 0) DEBUG_OFF (nsm, NSM_EVENTS); - else if (strncmp (argv[0], "t", 1) == 0) + else if (strncmp (argv[arg_base + 0], "t", 1) == 0) DEBUG_OFF (nsm, NSM_TIMERS); } @@ -1142,21 +1371,32 @@ DEFUN (no_debug_ospf_nsm, } /* ENABLE_NODE. */ - if (argc == 0) + if (argc == arg_base + 0) TERM_DEBUG_OFF (nsm, NSM); - else if (argc == 1) + else if (argc == arg_base + 1) { - if (strncmp (argv[0], "s", 1) == 0) + if (strncmp (argv[arg_base + 0], "s", 1) == 0) TERM_DEBUG_OFF (nsm, NSM_STATUS); - else if (strncmp (argv[0], "e", 1) == 0) + else if (strncmp (argv[arg_base + 0], "e", 1) == 0) TERM_DEBUG_OFF (nsm, NSM_EVENTS); - else if (strncmp (argv[0], "t", 1) == 0) + else if (strncmp (argv[arg_base + 0], "t", 1) == 0) TERM_DEBUG_OFF (nsm, NSM_TIMERS); } return CMD_SUCCESS; } +DEFUN (no_debug_ospf_nsm, + no_debug_ospf_nsm_cmd, + "no debug ospf nsm", + NO_STR + DEBUG_STR + OSPF_STR + "OSPF Neighbor State Machine") +{ + return no_debug_ospf_nsm_common(vty, 0, argc, argv); +} + ALIAS (no_debug_ospf_nsm, no_debug_ospf_nsm_sub_cmd, "no debug ospf nsm (status|events|timers)", @@ -1168,27 +1408,53 @@ ALIAS (no_debug_ospf_nsm, "NSM Event Information\n" "NSM Timer Information\n") - -DEFUN (debug_ospf_lsa, - debug_ospf_lsa_cmd, - "debug ospf lsa", +DEFUN (no_debug_ospf_instance_nsm, + no_debug_ospf_instance_nsm_cmd, + "no debug ospf <1-65535> nsm", + NO_STR DEBUG_STR OSPF_STR - "OSPF Link State Advertisement\n") + "Instance ID\n" + "OSPF Neighbor State Machine") +{ + u_short instance = 0; + + VTY_GET_INTEGER ("Instance", instance, argv[0]); + if (!ospf_lookup_instance (instance)) + return CMD_SUCCESS; + + return no_debug_ospf_nsm_common(vty, 1, argc, argv); +} + +ALIAS (no_debug_ospf_instance_nsm, + no_debug_ospf_instance_nsm_sub_cmd, + "no debug ospf <1-65535> nsm (status|events|timers)", + NO_STR + "Debugging functions\n" + "OSPF information\n" + "Instance ID\n" + "OSPF Interface State Machine\n" + "NSM Status Information\n" + "NSM Event Information\n" + "NSM Timer Information\n") + + +static int +debug_ospf_lsa_common (struct vty *vty, int arg_base, int argc, const char **argv) { if (vty->node == CONFIG_NODE) { - if (argc == 0) + if (argc == arg_base + 0) DEBUG_ON (lsa, LSA); - else if (argc == 1) + else if (argc == arg_base + 1) { - if (strncmp (argv[0], "g", 1) == 0) + if (strncmp (argv[arg_base + 0], "g", 1) == 0) DEBUG_ON (lsa, LSA_GENERATE); - else if (strncmp (argv[0], "f", 1) == 0) + else if (strncmp (argv[arg_base + 0], "f", 1) == 0) DEBUG_ON (lsa, LSA_FLOODING); - else if (strncmp (argv[0], "i", 1) == 0) + else if (strncmp (argv[arg_base + 0], "i", 1) == 0) DEBUG_ON (lsa, LSA_INSTALL); - else if (strncmp (argv[0], "r", 1) == 0) + else if (strncmp (argv[arg_base + 0], "r", 1) == 0) DEBUG_ON (lsa, LSA_REFRESH); } @@ -1196,23 +1462,33 @@ DEFUN (debug_ospf_lsa, } /* ENABLE_NODE. */ - if (argc == 0) + if (argc == arg_base + 0) TERM_DEBUG_ON (lsa, LSA); - else if (argc == 1) + else if (argc == arg_base + 1) { - if (strncmp (argv[0], "g", 1) == 0) + if (strncmp (argv[arg_base + 0], "g", 1) == 0) TERM_DEBUG_ON (lsa, LSA_GENERATE); - else if (strncmp (argv[0], "f", 1) == 0) + else if (strncmp (argv[arg_base + 0], "f", 1) == 0) TERM_DEBUG_ON (lsa, LSA_FLOODING); - else if (strncmp (argv[0], "i", 1) == 0) + else if (strncmp (argv[arg_base + 0], "i", 1) == 0) TERM_DEBUG_ON (lsa, LSA_INSTALL); - else if (strncmp (argv[0], "r", 1) == 0) + else if (strncmp (argv[arg_base + 0], "r", 1) == 0) TERM_DEBUG_ON (lsa, LSA_REFRESH); } return CMD_SUCCESS; } +DEFUN (debug_ospf_lsa, + debug_ospf_lsa_cmd, + "debug ospf lsa", + DEBUG_STR + OSPF_STR + "OSPF Link State Advertisement\n") +{ + return debug_ospf_lsa_common(vty, 0, argc, argv); +} + ALIAS (debug_ospf_lsa, debug_ospf_lsa_sub_cmd, "debug ospf lsa (generate|flooding|install|refresh)", @@ -1224,27 +1500,51 @@ ALIAS (debug_ospf_lsa, "LSA Install/Delete\n" "LSA Refresh\n") -DEFUN (no_debug_ospf_lsa, - no_debug_ospf_lsa_cmd, - "no debug ospf lsa", - NO_STR +DEFUN (debug_ospf_instance_lsa, + debug_ospf_instance_lsa_cmd, + "debug ospf <1-65535> lsa", DEBUG_STR OSPF_STR + "Instance ID\n" "OSPF Link State Advertisement\n") { + u_short instance = 0; + + VTY_GET_INTEGER ("Instance", instance, argv[0]); + if (!ospf_lookup_instance (instance)) + return CMD_SUCCESS; + + return debug_ospf_lsa_common(vty, 1, argc, argv); +} + +ALIAS (debug_ospf_instance_lsa, + debug_ospf_instance_lsa_sub_cmd, + "debug ospf <1-65535> lsa (generate|flooding|install|refresh)", + DEBUG_STR + OSPF_STR + "Instance ID\n" + "OSPF Link State Advertisement\n" + "LSA Generation\n" + "LSA Flooding\n" + "LSA Install/Delete\n" + "LSA Refresh\n") + +static int +no_debug_ospf_lsa_common (struct vty *vty, int arg_base, int argc, const char **argv) +{ if (vty->node == CONFIG_NODE) { - if (argc == 0) + if (argc == arg_base + 0) DEBUG_OFF (lsa, LSA); - else if (argc == 1) + else if (argc == arg_base + 1) { - if (strncmp (argv[0], "g", 1) == 0) + if (strncmp (argv[arg_base + 0], "g", 1) == 0) DEBUG_OFF (lsa, LSA_GENERATE); - else if (strncmp (argv[0], "f", 1) == 0) + else if (strncmp (argv[arg_base + 0], "f", 1) == 0) DEBUG_OFF (lsa, LSA_FLOODING); - else if (strncmp (argv[0], "i", 1) == 0) + else if (strncmp (argv[arg_base + 0], "i", 1) == 0) DEBUG_OFF (lsa, LSA_INSTALL); - else if (strncmp (argv[0], "r", 1) == 0) + else if (strncmp (argv[arg_base + 0], "r", 1) == 0) DEBUG_OFF (lsa, LSA_REFRESH); } @@ -1252,23 +1552,34 @@ DEFUN (no_debug_ospf_lsa, } /* ENABLE_NODE. */ - if (argc == 0) + if (argc == arg_base + 0) TERM_DEBUG_OFF (lsa, LSA); - else if (argc == 1) + else if (argc == arg_base + 1) { - if (strncmp (argv[0], "g", 1) == 0) + if (strncmp (argv[arg_base + 0], "g", 1) == 0) TERM_DEBUG_OFF (lsa, LSA_GENERATE); - else if (strncmp (argv[0], "f", 1) == 0) + else if (strncmp (argv[arg_base + 0], "f", 1) == 0) TERM_DEBUG_OFF (lsa, LSA_FLOODING); - else if (strncmp (argv[0], "i", 1) == 0) + else if (strncmp (argv[arg_base + 0], "i", 1) == 0) TERM_DEBUG_OFF (lsa, LSA_INSTALL); - else if (strncmp (argv[0], "r", 1) == 0) + else if (strncmp (argv[arg_base + 0], "r", 1) == 0) TERM_DEBUG_OFF (lsa, LSA_REFRESH); } return CMD_SUCCESS; } +DEFUN (no_debug_ospf_lsa, + no_debug_ospf_lsa_cmd, + "no debug ospf lsa", + NO_STR + DEBUG_STR + OSPF_STR + "OSPF Link State Advertisement\n") +{ + return no_debug_ospf_lsa_common (vty, 0, argc, argv); +} + ALIAS (no_debug_ospf_lsa, no_debug_ospf_lsa_sub_cmd, "no debug ospf lsa (generate|flooding|install|refresh)", @@ -1281,23 +1592,50 @@ ALIAS (no_debug_ospf_lsa, "LSA Install/Delete\n" "LSA Refres\n") +DEFUN (no_debug_ospf_instance_lsa, + no_debug_ospf_instance_lsa_cmd, + "no debug ospf <1-65535> lsa", + NO_STR + DEBUG_STR + OSPF_STR + "Instance ID\n" + "OSPF Link State Advertisement\n") +{ + u_short instance = 0; + + VTY_GET_INTEGER ("Instance", instance, argv[0]); + if (!ospf_lookup_instance (instance)) + return CMD_SUCCESS; -DEFUN (debug_ospf_zebra, - debug_ospf_zebra_cmd, - "debug ospf zebra", + return no_debug_ospf_lsa_common (vty, 1, argc, argv); +} + +ALIAS (no_debug_ospf_instance_lsa, + no_debug_ospf_instance_lsa_sub_cmd, + "no debug ospf <1-65535> lsa (generate|flooding|install|refresh)", + NO_STR DEBUG_STR OSPF_STR - "OSPF Zebra information\n") + "Instance ID\n" + "OSPF Link State Advertisement\n" + "LSA Generation\n" + "LSA Flooding\n" + "LSA Install/Delete\n" + "LSA Refres\n") + + +static int +debug_ospf_zebra_common (struct vty *vty, int arg_base, int argc, const char **argv) { if (vty->node == CONFIG_NODE) { - if (argc == 0) + if (argc == arg_base + 0) DEBUG_ON (zebra, ZEBRA); - else if (argc == 1) + else if (argc == arg_base + 1) { - if (strncmp (argv[0], "i", 1) == 0) + if (strncmp (argv[arg_base + 0], "i", 1) == 0) DEBUG_ON (zebra, ZEBRA_INTERFACE); - else if (strncmp (argv[0], "r", 1) == 0) + else if (strncmp (argv[arg_base + 0], "r", 1) == 0) DEBUG_ON (zebra, ZEBRA_REDISTRIBUTE); } @@ -1305,19 +1643,29 @@ DEFUN (debug_ospf_zebra, } /* ENABLE_NODE. */ - if (argc == 0) + if (argc == arg_base + 0) TERM_DEBUG_ON (zebra, ZEBRA); - else if (argc == 1) + else if (argc == arg_base + 1) { - if (strncmp (argv[0], "i", 1) == 0) + if (strncmp (argv[arg_base + 0], "i", 1) == 0) TERM_DEBUG_ON (zebra, ZEBRA_INTERFACE); - else if (strncmp (argv[0], "r", 1) == 0) + else if (strncmp (argv[arg_base + 0], "r", 1) == 0) TERM_DEBUG_ON (zebra, ZEBRA_REDISTRIBUTE); } return CMD_SUCCESS; } +DEFUN (debug_ospf_zebra, + debug_ospf_zebra_cmd, + "debug ospf zebra", + DEBUG_STR + OSPF_STR + "OSPF Zebra information\n") +{ + return debug_ospf_zebra_common(vty, 0, argc, argv); +} + ALIAS (debug_ospf_zebra, debug_ospf_zebra_sub_cmd, "debug ospf zebra (interface|redistribute)", @@ -1327,23 +1675,46 @@ ALIAS (debug_ospf_zebra, "Zebra interface\n" "Zebra redistribute\n") -DEFUN (no_debug_ospf_zebra, - no_debug_ospf_zebra_cmd, - "no debug ospf zebra", - NO_STR +DEFUN (debug_ospf_instance_zebra, + debug_ospf_instance_zebra_cmd, + "debug ospf <1-65535> zebra", DEBUG_STR OSPF_STR + "Instance ID\n" "OSPF Zebra information\n") { + u_short instance = 0; + + VTY_GET_INTEGER ("Instance", instance, argv[0]); + if (!ospf_lookup_instance (instance)) + return CMD_SUCCESS; + + return debug_ospf_zebra_common(vty, 1, argc, argv); +} + +ALIAS (debug_ospf_instance_zebra, + debug_ospf_instance_zebra_sub_cmd, + "debug ospf <1-65535> zebra (interface|redistribute)", + DEBUG_STR + OSPF_STR + "Instance ID\n" + "OSPF Zebra information\n" + "Zebra interface\n" + "Zebra redistribute\n") + +static int +no_debug_ospf_zebra_common(struct vty *vty, int arg_base, int argc, + const char **argv) +{ if (vty->node == CONFIG_NODE) { - if (argc == 0) + if (argc == arg_base + 0) DEBUG_OFF (zebra, ZEBRA); - else if (argc == 1) + else if (argc == arg_base + 1) { - if (strncmp (argv[0], "i", 1) == 0) + if (strncmp (argv[arg_base + 0], "i", 1) == 0) DEBUG_OFF (zebra, ZEBRA_INTERFACE); - else if (strncmp (argv[0], "r", 1) == 0) + else if (strncmp (argv[arg_base + 0], "r", 1) == 0) DEBUG_OFF (zebra, ZEBRA_REDISTRIBUTE); } @@ -1351,19 +1722,30 @@ DEFUN (no_debug_ospf_zebra, } /* ENABLE_NODE. */ - if (argc == 0) + if (argc == arg_base + 0) TERM_DEBUG_OFF (zebra, ZEBRA); - else if (argc == 1) + else if (argc == arg_base + 1) { - if (strncmp (argv[0], "i", 1) == 0) + if (strncmp (argv[arg_base + 0], "i", 1) == 0) TERM_DEBUG_OFF (zebra, ZEBRA_INTERFACE); - else if (strncmp (argv[0], "r", 1) == 0) + else if (strncmp (argv[arg_base + 0], "r", 1) == 0) TERM_DEBUG_OFF (zebra, ZEBRA_REDISTRIBUTE); } return CMD_SUCCESS; } +DEFUN (no_debug_ospf_zebra, + no_debug_ospf_zebra_cmd, + "no debug ospf zebra", + NO_STR + DEBUG_STR + OSPF_STR + "OSPF Zebra information\n") +{ + return no_debug_ospf_zebra_common(vty, 0, argc, argv); +} + ALIAS (no_debug_ospf_zebra, no_debug_ospf_zebra_sub_cmd, "no debug ospf zebra (interface|redistribute)", @@ -1374,6 +1756,36 @@ ALIAS (no_debug_ospf_zebra, "Zebra interface\n" "Zebra redistribute\n") +DEFUN (no_debug_ospf_instance_zebra, + no_debug_ospf_instance_zebra_cmd, + "no debug ospf <1-65535> zebra", + NO_STR + DEBUG_STR + OSPF_STR + "Instance ID\n" + "OSPF Zebra information\n") +{ + u_short instance = 0; + + VTY_GET_INTEGER ("Instance", instance, argv[0]); + if (!ospf_lookup_instance (instance)) + return CMD_SUCCESS; + + return no_debug_ospf_zebra_common(vty, 1, argc, argv); +} + +ALIAS (no_debug_ospf_instance_zebra, + no_debug_ospf_instance_zebra_sub_cmd, + "no debug ospf <1-65535> zebra (interface|redistribute)", + NO_STR + DEBUG_STR + OSPF_STR + "Instance ID\n" + "OSPF Zebra information\n" + "Zebra interface\n" + "Zebra redistribute\n") + + DEFUN (debug_ospf_event, debug_ospf_event_cmd, "debug ospf event", @@ -1401,6 +1813,47 @@ DEFUN (no_debug_ospf_event, return CMD_SUCCESS; } +DEFUN (debug_ospf_instance_event, + debug_ospf_instance_event_cmd, + "debug ospf <1-65535> event", + DEBUG_STR + OSPF_STR + "Instance ID\n" + "OSPF event information\n") +{ + u_short instance = 0; + + VTY_GET_INTEGER ("Instance", instance, argv[0]); + if (!ospf_lookup_instance (instance)) + return CMD_SUCCESS; + + if (vty->node == CONFIG_NODE) + CONF_DEBUG_ON (event, EVENT); + TERM_DEBUG_ON (event, EVENT); + return CMD_SUCCESS; +} + +DEFUN (no_debug_ospf_instance_event, + no_debug_ospf_instance_event_cmd, + "no debug ospf <1-65535> event", + NO_STR + DEBUG_STR + OSPF_STR + "Instance ID\n" + "OSPF event information\n") +{ + u_short instance = 0; + + VTY_GET_INTEGER ("Instance", instance, argv[0]); + if (!ospf_lookup_instance (instance)) + return CMD_SUCCESS; + + if (vty->node == CONFIG_NODE) + CONF_DEBUG_OFF (event, EVENT); + TERM_DEBUG_OFF (event, EVENT); + return CMD_SUCCESS; +} + DEFUN (debug_ospf_nssa, debug_ospf_nssa_cmd, "debug ospf nssa", @@ -1428,16 +1881,57 @@ DEFUN (no_debug_ospf_nssa, return CMD_SUCCESS; } +DEFUN (debug_ospf_instance_nssa, + debug_ospf_instance_nssa_cmd, + "debug ospf <1-65535> nssa", + DEBUG_STR + OSPF_STR + "Instance ID\n" + "OSPF nssa information\n") +{ + u_short instance = 0; + + VTY_GET_INTEGER ("Instance", instance, argv[0]); + if (!ospf_lookup_instance (instance)) + return CMD_SUCCESS; -DEFUN (show_debugging_ospf, - show_debugging_ospf_cmd, - "show debugging ospf", - SHOW_STR + if (vty->node == CONFIG_NODE) + CONF_DEBUG_ON (nssa, NSSA); + TERM_DEBUG_ON (nssa, NSSA); + return CMD_SUCCESS; +} + +DEFUN (no_debug_ospf_instance_nssa, + no_debug_ospf_instance_nssa_cmd, + "no debug ospf <1-65535> nssa", + NO_STR DEBUG_STR - OSPF_STR) + OSPF_STR + "Instance ID\n" + "OSPF nssa information\n") +{ + u_short instance = 0; + + VTY_GET_INTEGER ("Instance", instance, argv[0]); + if (!ospf_lookup_instance (instance)) + return CMD_SUCCESS; + + if (vty->node == CONFIG_NODE) + CONF_DEBUG_OFF (nssa, NSSA); + TERM_DEBUG_OFF (nssa, NSSA); + return CMD_SUCCESS; +} + + +static int +show_debugging_ospf_common (struct vty *vty, struct ospf *ospf) { int i; + if (ospf->instance) + vty_out (vty, "%sOSPF Instance: %d%s%s", VTY_NEWLINE, ospf->instance, + VTY_NEWLINE, VTY_NEWLINE); + vty_out (vty, "OSPF debugging status:%s", VTY_NEWLINE); /* Show debug status for events. */ @@ -1523,9 +2017,44 @@ DEFUN (show_debugging_ospf, if (IS_DEBUG_OSPF (nssa, NSSA) == OSPF_DEBUG_NSSA) vty_out (vty, " OSPF NSSA debugging is on%s", VTY_NEWLINE); + vty_out (vty, "%s", VTY_NEWLINE); + return CMD_SUCCESS; } +DEFUN (show_debugging_ospf, + show_debugging_ospf_cmd, + "show debugging ospf", + SHOW_STR + DEBUG_STR + OSPF_STR) +{ + struct ospf *ospf; + + if ((ospf = ospf_lookup()) == NULL) + return CMD_SUCCESS; + + return show_debugging_ospf_common(vty, ospf); +} + +DEFUN (show_debugging_ospf_instance, + show_debugging_ospf_instance_cmd, + "show debugging ospf <1-65535>", + SHOW_STR + DEBUG_STR + OSPF_STR + "Instance ID\n") +{ + struct ospf *ospf; + u_short instance = 0; + + VTY_GET_INTEGER ("Instance", instance, argv[0]); + if ((ospf = ospf_lookup_instance (instance)) == NULL ) + return CMD_SUCCESS; + + return show_debugging_ospf_common(vty, ospf); +} + /* Debug node. */ static struct cmd_node debug_node = { @@ -1544,58 +2073,69 @@ config_write_debug (struct vty *vty) const char *detail_str[] = {"", " send", " recv", "", " detail", " send detail", " recv detail", " detail"}; + struct ospf *ospf; + char str[16]; + + if ((ospf = ospf_lookup()) == NULL) + return CMD_SUCCESS; + + if (ospf->instance) + sprintf(str, " %d", ospf->instance); + else + sprintf(str, ""); + /* debug ospf ism (status|events|timers). */ if (IS_CONF_DEBUG_OSPF (ism, ISM) == OSPF_DEBUG_ISM) - vty_out (vty, "debug ospf ism%s", VTY_NEWLINE); + vty_out (vty, "debug ospf%s ism%s", str, VTY_NEWLINE); else { if (IS_CONF_DEBUG_OSPF (ism, ISM_STATUS)) - vty_out (vty, "debug ospf ism status%s", VTY_NEWLINE); + vty_out (vty, "debug ospf%s ism status%s", str, VTY_NEWLINE); if (IS_CONF_DEBUG_OSPF (ism, ISM_EVENTS)) - vty_out (vty, "debug ospf ism event%s", VTY_NEWLINE); + vty_out (vty, "debug ospf%s ism event%s", str, VTY_NEWLINE); if (IS_CONF_DEBUG_OSPF (ism, ISM_TIMERS)) - vty_out (vty, "debug ospf ism timer%s", VTY_NEWLINE); + vty_out (vty, "debug ospf%s ism timer%s", str, VTY_NEWLINE); } /* debug ospf nsm (status|events|timers). */ if (IS_CONF_DEBUG_OSPF (nsm, NSM) == OSPF_DEBUG_NSM) - vty_out (vty, "debug ospf nsm%s", VTY_NEWLINE); + vty_out (vty, "debug ospf%s nsm%s", str, VTY_NEWLINE); else { if (IS_CONF_DEBUG_OSPF (nsm, NSM_STATUS)) - vty_out (vty, "debug ospf nsm status%s", VTY_NEWLINE); + vty_out (vty, "debug ospf%s nsm status%s", str, VTY_NEWLINE); if (IS_CONF_DEBUG_OSPF (nsm, NSM_EVENTS)) - vty_out (vty, "debug ospf nsm event%s", VTY_NEWLINE); + vty_out (vty, "debug ospf%s nsm event%s", str, VTY_NEWLINE); if (IS_CONF_DEBUG_OSPF (nsm, NSM_TIMERS)) - vty_out (vty, "debug ospf nsm timer%s", VTY_NEWLINE); + vty_out (vty, "debug ospf%s nsm timer%s", str, VTY_NEWLINE); } /* debug ospf lsa (generate|flooding|install|refresh). */ if (IS_CONF_DEBUG_OSPF (lsa, LSA) == OSPF_DEBUG_LSA) - vty_out (vty, "debug ospf lsa%s", VTY_NEWLINE); + vty_out (vty, "debug ospf%s lsa%s", str, VTY_NEWLINE); else { if (IS_CONF_DEBUG_OSPF (lsa, LSA_GENERATE)) - vty_out (vty, "debug ospf lsa generate%s", VTY_NEWLINE); + vty_out (vty, "debug ospf%s lsa generate%s", str, VTY_NEWLINE); if (IS_CONF_DEBUG_OSPF (lsa, LSA_FLOODING)) - vty_out (vty, "debug ospf lsa flooding%s", VTY_NEWLINE); + vty_out (vty, "debug ospf%s lsa flooding%s", str, VTY_NEWLINE); if (IS_CONF_DEBUG_OSPF (lsa, LSA_INSTALL)) - vty_out (vty, "debug ospf lsa install%s", VTY_NEWLINE); + vty_out (vty, "debug ospf%s lsa install%s", str, VTY_NEWLINE); if (IS_CONF_DEBUG_OSPF (lsa, LSA_REFRESH)) - vty_out (vty, "debug ospf lsa refresh%s", VTY_NEWLINE); + vty_out (vty, "debug ospf%s lsa refresh%s", str, VTY_NEWLINE); write = 1; } /* debug ospf zebra (interface|redistribute). */ if (IS_CONF_DEBUG_OSPF (zebra, ZEBRA) == OSPF_DEBUG_ZEBRA) - vty_out (vty, "debug ospf zebra%s", VTY_NEWLINE); + vty_out (vty, "debug ospf%s zebra%s", str, VTY_NEWLINE); else { if (IS_CONF_DEBUG_OSPF (zebra, ZEBRA_INTERFACE)) - vty_out (vty, "debug ospf zebra interface%s", VTY_NEWLINE); + vty_out (vty, "debug ospf%s zebra interface%s", str, VTY_NEWLINE); if (IS_CONF_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE)) - vty_out (vty, "debug ospf zebra redistribute%s", VTY_NEWLINE); + vty_out (vty, "debug ospf%s zebra redistribute%s", str, VTY_NEWLINE); write = 1; } @@ -1603,14 +2143,14 @@ config_write_debug (struct vty *vty) /* debug ospf event. */ if (IS_CONF_DEBUG_OSPF (event, EVENT) == OSPF_DEBUG_EVENT) { - vty_out (vty, "debug ospf event%s", VTY_NEWLINE); + vty_out (vty, "debug ospf%s event%s", str, VTY_NEWLINE); write = 1; } /* debug ospf nssa. */ if (IS_CONF_DEBUG_OSPF (nssa, NSSA) == OSPF_DEBUG_NSSA) { - vty_out (vty, "debug ospf nssa%s", VTY_NEWLINE); + vty_out (vty, "debug ospf%s nssa%s", str, VTY_NEWLINE); write = 1; } @@ -1620,7 +2160,7 @@ config_write_debug (struct vty *vty) r &= conf_debug_ospf_packet[i] & (OSPF_DEBUG_SEND_RECV|OSPF_DEBUG_DETAIL); if (r == (OSPF_DEBUG_SEND_RECV|OSPF_DEBUG_DETAIL)) { - vty_out (vty, "debug ospf packet all detail%s", VTY_NEWLINE); + vty_out (vty, "debug ospf%s packet all detail%s", str, VTY_NEWLINE); return 1; } @@ -1630,10 +2170,10 @@ config_write_debug (struct vty *vty) r &= conf_debug_ospf_packet[i] & OSPF_DEBUG_SEND_RECV; if (r == OSPF_DEBUG_SEND_RECV) { - vty_out (vty, "debug ospf packet all%s", VTY_NEWLINE); + vty_out (vty, "debug ospf%s packet all%s", str, VTY_NEWLINE); for (i = 0; i < 5; i++) if (conf_debug_ospf_packet[i] & OSPF_DEBUG_DETAIL) - vty_out (vty, "debug ospf packet %s detail%s", + vty_out (vty, "debug ospf%s packet %s detail%s", str, type_str[i], VTY_NEWLINE); return 1; @@ -1646,7 +2186,7 @@ config_write_debug (struct vty *vty) if (conf_debug_ospf_packet[i] == 0) continue; - vty_out (vty, "debug ospf packet %s%s%s", + vty_out (vty, "debug ospf%s packet %s%s%s", str, type_str[i], detail_str[conf_debug_ospf_packet[i]], VTY_NEWLINE); write = 1; @@ -1689,6 +2229,34 @@ debug_init () install_element (ENABLE_NODE, &no_debug_ospf_event_cmd); install_element (ENABLE_NODE, &no_debug_ospf_nssa_cmd); + install_element (ENABLE_NODE, &show_debugging_ospf_instance_cmd); + install_element (ENABLE_NODE, &debug_ospf_instance_packet_send_recv_detail_cmd); + install_element (ENABLE_NODE, &debug_ospf_instance_packet_send_recv_cmd); + install_element (ENABLE_NODE, &debug_ospf_instance_packet_all_cmd); + install_element (ENABLE_NODE, &debug_ospf_instance_ism_sub_cmd); + install_element (ENABLE_NODE, &debug_ospf_instance_ism_cmd); + install_element (ENABLE_NODE, &debug_ospf_instance_nsm_sub_cmd); + install_element (ENABLE_NODE, &debug_ospf_instance_nsm_cmd); + install_element (ENABLE_NODE, &debug_ospf_instance_lsa_sub_cmd); + install_element (ENABLE_NODE, &debug_ospf_instance_lsa_cmd); + install_element (ENABLE_NODE, &debug_ospf_instance_zebra_sub_cmd); + install_element (ENABLE_NODE, &debug_ospf_instance_zebra_cmd); + install_element (ENABLE_NODE, &debug_ospf_instance_event_cmd); + install_element (ENABLE_NODE, &debug_ospf_instance_nssa_cmd); + install_element (ENABLE_NODE, &no_debug_ospf_instance_packet_send_recv_detail_cmd); + install_element (ENABLE_NODE, &no_debug_ospf_instance_packet_send_recv_cmd); + install_element (ENABLE_NODE, &no_debug_ospf_instance_packet_all_cmd); + install_element (ENABLE_NODE, &no_debug_ospf_instance_ism_sub_cmd); + install_element (ENABLE_NODE, &no_debug_ospf_instance_ism_cmd); + install_element (ENABLE_NODE, &no_debug_ospf_instance_nsm_sub_cmd); + install_element (ENABLE_NODE, &no_debug_ospf_instance_nsm_cmd); + install_element (ENABLE_NODE, &no_debug_ospf_instance_lsa_sub_cmd); + install_element (ENABLE_NODE, &no_debug_ospf_instance_lsa_cmd); + install_element (ENABLE_NODE, &no_debug_ospf_instance_zebra_sub_cmd); + install_element (ENABLE_NODE, &no_debug_ospf_instance_zebra_cmd); + install_element (ENABLE_NODE, &no_debug_ospf_instance_event_cmd); + install_element (ENABLE_NODE, &no_debug_ospf_instance_nssa_cmd); + install_element (CONFIG_NODE, &debug_ospf_packet_send_recv_detail_cmd); install_element (CONFIG_NODE, &debug_ospf_packet_send_recv_cmd); install_element (CONFIG_NODE, &debug_ospf_packet_all_cmd); @@ -1715,4 +2283,31 @@ debug_init () install_element (CONFIG_NODE, &no_debug_ospf_zebra_cmd); install_element (CONFIG_NODE, &no_debug_ospf_event_cmd); install_element (CONFIG_NODE, &no_debug_ospf_nssa_cmd); + + install_element (CONFIG_NODE, &debug_ospf_instance_packet_send_recv_detail_cmd); + install_element (CONFIG_NODE, &debug_ospf_instance_packet_send_recv_cmd); + install_element (CONFIG_NODE, &debug_ospf_instance_packet_all_cmd); + install_element (CONFIG_NODE, &debug_ospf_instance_ism_sub_cmd); + install_element (CONFIG_NODE, &debug_ospf_instance_ism_cmd); + install_element (CONFIG_NODE, &debug_ospf_instance_nsm_sub_cmd); + install_element (CONFIG_NODE, &debug_ospf_instance_nsm_cmd); + install_element (CONFIG_NODE, &debug_ospf_instance_lsa_sub_cmd); + install_element (CONFIG_NODE, &debug_ospf_instance_lsa_cmd); + install_element (CONFIG_NODE, &debug_ospf_instance_zebra_sub_cmd); + install_element (CONFIG_NODE, &debug_ospf_instance_zebra_cmd); + install_element (CONFIG_NODE, &debug_ospf_instance_event_cmd); + install_element (CONFIG_NODE, &debug_ospf_instance_nssa_cmd); + install_element (CONFIG_NODE, &no_debug_ospf_instance_packet_send_recv_detail_cmd); + install_element (CONFIG_NODE, &no_debug_ospf_instance_packet_send_recv_cmd); + install_element (CONFIG_NODE, &no_debug_ospf_instance_packet_all_cmd); + install_element (CONFIG_NODE, &no_debug_ospf_instance_ism_sub_cmd); + install_element (CONFIG_NODE, &no_debug_ospf_instance_ism_cmd); + install_element (CONFIG_NODE, &no_debug_ospf_instance_nsm_sub_cmd); + install_element (CONFIG_NODE, &no_debug_ospf_instance_nsm_cmd); + install_element (CONFIG_NODE, &no_debug_ospf_instance_lsa_sub_cmd); + install_element (CONFIG_NODE, &no_debug_ospf_instance_lsa_cmd); + install_element (CONFIG_NODE, &no_debug_ospf_instance_zebra_sub_cmd); + install_element (CONFIG_NODE, &no_debug_ospf_instance_zebra_cmd); + install_element (CONFIG_NODE, &no_debug_ospf_instance_event_cmd); + install_element (CONFIG_NODE, &no_debug_ospf_instance_nssa_cmd); } diff --git a/ospfd/ospf_flood.c b/ospfd/ospf_flood.c index d18314a9d..1d107ca0d 100644 --- a/ospfd/ospf_flood.c +++ b/ospfd/ospf_flood.c @@ -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; diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c index 1de03440c..f988468e3 100644 --- a/ospfd/ospf_lsa.c +++ b/ospfd/ospf_lsa.c @@ -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)) { diff --git a/ospfd/ospf_lsa.h b/ospfd/ospf_lsa.h index c71877da4..624efc4c1 100644 --- a/ospfd/ospf_lsa.h +++ b/ospfd/ospf_lsa.h @@ -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 *); diff --git a/ospfd/ospf_main.c b/ospfd/ospf_main.c index 19b9121cc..d34e65dc4 100644 --- a/ospfd/ospf_main.c +++ b/ospfd/ospf_main.c @@ -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)) diff --git a/ospfd/ospf_nsm.c b/ospfd/ospf_nsm.c index d3266e835..2cbd04bbe 100644 --- a/ospfd/ospf_nsm.c +++ b/ospfd/ospf_nsm.c @@ -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 diff --git a/ospfd/ospf_opaque.c b/ospfd/ospf_opaque.c index 744952c96..999893ff1 100644 --- a/ospfd/ospf_opaque.c +++ b/ospfd/ospf_opaque.c @@ -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)) { diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c index ff1bdae59..491b9c54b 100644 --- a/ospfd/ospf_packet.c +++ b/ospfd/ospf_packet.c @@ -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); diff --git a/ospfd/ospf_routemap.c b/ospfd/ospf_routemap.c index 425524d48..6e02de3a1 100644 --- a/ospfd/ospf_routemap.c +++ b/ospfd/ospf_routemap.c @@ -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); - - /* Update route-map. */ - ROUTEMAP (ospf, type) = - route_map_lookup_by_name (ROUTEMAP_NAME (ospf, type)); - - /* No update for this distribute type. */ - if (old == NULL && ROUTEMAP (ospf, type) == NULL) - continue; - - ospf_distribute_list_update (ospf, type); - } + 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)) + { + if (ROUTEMAP_NAME (red) + && strcmp (ROUTEMAP_NAME (red), name) == 0) + { + /* Keep old route-map. */ + struct route_map *old = ROUTEMAP (red); + + /* 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); + } } } } diff --git a/ospfd/ospf_te.c b/ospfd/ospf_te.c index c605ce68d..e7e1a4362 100644 --- a/ospfd/ospf_te.c +++ b/ospfd/ospf_te.c @@ -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)) { diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index 2854a41b4..4f0727b58 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -149,12 +149,38 @@ DEFUN (router_ospf, "Enable a routing process\n" "Start OSPF configuration\n") { + struct ospf *ospf; + u_short instance = 0; + + ospf = ospf_lookup(); + if (!ospf) + { + vty_out (vty, "There isn't active ospf instance %s", VTY_NEWLINE); + return CMD_WARNING; + } + vty->node = OSPF_NODE; - vty->index = ospf_get (); + + if (argc) + VTY_GET_INTEGER ("Instance", instance, argv[0]); + + /* The following logic to set the vty->index is in place to be able + to ignore the commands which dont belong to this instance. */ + if (ospf->instance != instance) + vty->index = NULL; + else + vty->index = ospf; return CMD_SUCCESS; } +ALIAS (router_ospf, + router_ospf_instance_cmd, + "router ospf <1-65535>", + "Enable a routing process\n" + "Start OSPF configuration\n" + "Instance ID\n") + DEFUN (no_router_ospf, no_router_ospf_cmd, "no router ospf", @@ -163,19 +189,27 @@ DEFUN (no_router_ospf, "Start OSPF configuration\n") { struct ospf *ospf; + u_short instance = 0; - ospf = ospf_lookup (); - if (ospf == NULL) - { - vty_out (vty, "There isn't active ospf instance%s", VTY_NEWLINE); - return CMD_WARNING; - } + if (argc) + VTY_GET_INTEGER ("Instance", instance, argv[0]); + + if ((ospf = ospf_lookup_instance (instance)) == NULL) + return CMD_SUCCESS; ospf_finish (ospf); return CMD_SUCCESS; } +ALIAS (no_router_ospf, + no_router_ospf_instance_cmd, + "no router ospf <1-65535>", + NO_STR + "Enable a routing process\n" + "Start OSPF configuration\n" + "Instance ID\n") + DEFUN (ospf_router_id, ospf_router_id_cmd, "ospf router-id A.B.C.D", @@ -187,6 +221,9 @@ DEFUN (ospf_router_id, struct in_addr router_id; int ret; + if (!ospf) + return CMD_SUCCESS; + ret = inet_aton (argv[0], &router_id); if (!ret) { @@ -216,6 +253,9 @@ DEFUN (no_ospf_router_id, { struct ospf *ospf = vty->index; + if (!ospf) + return CMD_SUCCESS; + ospf->router_id_static.s_addr = 0; ospf_router_id_update (ospf); @@ -298,6 +338,9 @@ DEFUN (ospf_passive_interface, struct route_node *rn; struct ospf *ospf = vty->index; + if (!ospf) + return CMD_SUCCESS; + if (argc == 0) { ospf_passive_interface_default (ospf, OSPF_IF_PASSIVE); @@ -374,6 +417,9 @@ DEFUN (no_ospf_passive_interface, struct route_node *rn; struct ospf *ospf = vty->index; + if (!ospf) + return CMD_SUCCESS; + if (argc == 0) { ospf_passive_interface_default (ospf, OSPF_IF_ACTIVE); @@ -446,6 +492,16 @@ DEFUN (ospf_network_area, struct in_addr area_id; int ret, format; + if (!ospf) + return CMD_SUCCESS; + + if (ospf->instance) + { + vty_out (vty, "The network command is not supported in multi-instance ospf%s", + VTY_NEWLINE); + return CMD_WARNING; + } + if (ospf->if_ospf_cli_count > 0) { vty_out (vty, "Please remove all ip ospf area x.x.x.x commands first.%s", @@ -482,6 +538,16 @@ DEFUN (no_ospf_network_area, struct in_addr area_id; int ret, format; + if (!ospf) + return CMD_SUCCESS; + + if (ospf->instance) + { + vty_out (vty, "The network command is not supported in multi-instance ospf%s", + VTY_NEWLINE); + return CMD_WARNING; + } + /* Get network prefix and Area ID. */ VTY_GET_IPV4_PREFIX ("network prefix", p, argv[0]); VTY_GET_OSPF_AREA_ID (area_id, format, argv[1]); @@ -513,6 +579,9 @@ DEFUN (ospf_area_range, int format; u_int32_t cost; + if (!ospf) + return CMD_SUCCESS; + VTY_GET_OSPF_AREA_ID (area_id, format, argv[0]); VTY_GET_IPV4_PREFIX ("area range", p, argv[1]); @@ -574,6 +643,9 @@ DEFUN (ospf_area_range_not_advertise, struct in_addr area_id; int format; + if (!ospf) + return CMD_SUCCESS; + VTY_GET_OSPF_AREA_ID (area_id, format, argv[0]); VTY_GET_IPV4_PREFIX ("area range", p, argv[1]); @@ -597,6 +669,9 @@ DEFUN (no_ospf_area_range, struct in_addr area_id; int format; + if (!ospf) + return CMD_SUCCESS; + VTY_GET_OSPF_AREA_ID (area_id, format, argv[0]); VTY_GET_IPV4_PREFIX ("area range", p, argv[1]); @@ -658,6 +733,9 @@ DEFUN (ospf_area_range_substitute, struct in_addr area_id; int format; + if (!ospf) + return CMD_SUCCESS; + VTY_GET_OSPF_AREA_ID (area_id, format, argv[0]); VTY_GET_IPV4_PREFIX ("area range", p, argv[1]); VTY_GET_IPV4_PREFIX ("substituted network prefix", s, argv[2]); @@ -684,6 +762,9 @@ DEFUN (no_ospf_area_range_substitute, struct in_addr area_id; int format; + if (!ospf) + return CMD_SUCCESS; + VTY_GET_OSPF_AREA_ID (area_id, format, argv[0]); VTY_GET_IPV4_PREFIX ("area range", p, argv[1]); VTY_GET_IPV4_PREFIX ("substituted network prefix", s, argv[2]); @@ -959,6 +1040,9 @@ DEFUN (ospf_area_vlink, int i; int ret; + if (!ospf) + return CMD_SUCCESS; + ospf_vl_config_data_init(&vl_config, vty); /* Read off first 2 parameters and check them */ @@ -1095,6 +1179,9 @@ DEFUN (no_ospf_area_vlink, int i; int ret, format; + if (!ospf) + return CMD_SUCCESS; + ospf_vl_config_data_init(&vl_config, vty); ret = ospf_str2area_id (argv[0], &vl_config.area_id, &format); @@ -1407,6 +1494,9 @@ DEFUN (ospf_area_shortcut, int mode; int format; + if (!ospf) + return CMD_SUCCESS; + VTY_GET_OSPF_AREA_ID_NO_BB ("shortcut", area_id, format, argv[0]); area = ospf_area_get (ospf, area_id, format); @@ -1446,6 +1536,9 @@ DEFUN (no_ospf_area_shortcut, struct in_addr area_id; int format; + if (!ospf) + return CMD_SUCCESS; + VTY_GET_OSPF_AREA_ID_NO_BB ("shortcut", area_id, format, argv[0]); area = ospf_area_lookup_by_area_id (ospf, area_id); @@ -1470,6 +1563,9 @@ DEFUN (ospf_area_stub, struct in_addr area_id; int ret, format; + if (!ospf) + return CMD_SUCCESS; + VTY_GET_OSPF_AREA_ID_NO_BB ("stub", area_id, format, argv[0]); ret = ospf_area_stub_set (ospf, area_id); @@ -1498,6 +1594,9 @@ DEFUN (ospf_area_stub_no_summary, struct in_addr area_id; int ret, format; + if (!ospf) + return CMD_SUCCESS; + VTY_GET_OSPF_AREA_ID_NO_BB ("stub", area_id, format, argv[0]); ret = ospf_area_stub_set (ospf, area_id); @@ -1526,6 +1625,9 @@ DEFUN (no_ospf_area_stub, struct in_addr area_id; int format; + if (!ospf) + return CMD_SUCCESS; + VTY_GET_OSPF_AREA_ID_NO_BB ("stub", area_id, format, argv[0]); ospf_area_stub_unset (ospf, area_id); @@ -1548,6 +1650,9 @@ DEFUN (no_ospf_area_stub_no_summary, struct in_addr area_id; int format; + if (!ospf) + return CMD_SUCCESS; + VTY_GET_OSPF_AREA_ID_NO_BB ("stub", area_id, format, argv[0]); ospf_area_no_summary_unset (ospf, area_id); @@ -1562,6 +1667,9 @@ ospf_area_nssa_cmd_handler (struct vty *vty, int argc, const char *argv[], struct in_addr area_id; int ret, format; + if (!ospf) + return CMD_SUCCESS; + VTY_GET_OSPF_AREA_ID_NO_BB ("NSSA", area_id, format, argv[0]); ret = ospf_area_nssa_set (ospf, area_id); @@ -1665,6 +1773,9 @@ DEFUN (no_ospf_area_nssa, struct in_addr area_id; int format; + if (!ospf) + return CMD_SUCCESS; + VTY_GET_OSPF_AREA_ID_NO_BB ("NSSA", area_id, format, argv[0]); ospf_area_nssa_unset (ospf, area_id); @@ -1689,6 +1800,9 @@ DEFUN (no_ospf_area_nssa_no_summary, struct in_addr area_id; int format; + if (!ospf) + return CMD_SUCCESS; + VTY_GET_OSPF_AREA_ID_NO_BB ("NSSA", area_id, format, argv[0]); ospf_area_no_summary_unset (ospf, area_id); @@ -1711,6 +1825,9 @@ DEFUN (ospf_area_default_cost, int format; struct prefix_ipv4 p; + if (!ospf) + return CMD_SUCCESS; + VTY_GET_OSPF_AREA_ID_NO_BB ("default-cost", area_id, format, argv[0]); VTY_GET_INTEGER_RANGE ("stub default cost", cost, argv[1], 0, 16777215); @@ -1752,6 +1869,9 @@ DEFUN (no_ospf_area_default_cost, int format; struct prefix_ipv4 p; + if (!ospf) + return CMD_SUCCESS; + VTY_GET_OSPF_AREA_ID_NO_BB ("default-cost", area_id, format, argv[0]); VTY_CHECK_INTEGER_RANGE ("stub default cost", argv[1], 0, OSPF_LS_INFINITY); @@ -1796,6 +1916,9 @@ DEFUN (ospf_area_export_list, struct in_addr area_id; int format; + if (!ospf) + return CMD_SUCCESS; + VTY_GET_OSPF_AREA_ID (area_id, format, argv[0]); area = ospf_area_get (ospf, area_id, format); @@ -1819,6 +1942,9 @@ DEFUN (no_ospf_area_export_list, struct in_addr area_id; int format; + if (!ospf) + return CMD_SUCCESS; + VTY_GET_OSPF_AREA_ID (area_id, format, argv[0]); area = ospf_area_lookup_by_area_id (ospf, area_id); @@ -1845,6 +1971,9 @@ DEFUN (ospf_area_import_list, struct in_addr area_id; int format; + if (!ospf) + return CMD_SUCCESS; + VTY_GET_OSPF_AREA_ID (area_id, format, argv[0]); area = ospf_area_get (ospf, area_id, format); @@ -1868,6 +1997,9 @@ DEFUN (no_ospf_area_import_list, struct in_addr area_id; int format; + if (!ospf) + return CMD_SUCCESS; + VTY_GET_OSPF_AREA_ID (area_id, format, argv[0]); area = ospf_area_lookup_by_area_id (ospf, area_id); @@ -1897,6 +2029,9 @@ DEFUN (ospf_area_filter_list, struct prefix_list *plist; int format; + if (!ospf) + return CMD_SUCCESS; + VTY_GET_OSPF_AREA_ID (area_id, format, argv[0]); area = ospf_area_get (ospf, area_id, format); @@ -1941,6 +2076,9 @@ DEFUN (no_ospf_area_filter_list, struct in_addr area_id; int format; + if (!ospf) + return CMD_SUCCESS; + VTY_GET_OSPF_AREA_ID (area_id, format, argv[0]); if ((area = ospf_area_lookup_by_area_id (ospf, area_id)) == NULL) @@ -1993,6 +2131,9 @@ DEFUN (ospf_area_authentication_message_digest, struct in_addr area_id; int format; + if (!ospf) + return CMD_SUCCESS; + VTY_GET_OSPF_AREA_ID (area_id, format, argv[0]); area = ospf_area_get (ospf, area_id, format); @@ -2014,6 +2155,9 @@ DEFUN (ospf_area_authentication, struct in_addr area_id; int format; + if (!ospf) + return CMD_SUCCESS; + VTY_GET_OSPF_AREA_ID (area_id, format, argv[0]); area = ospf_area_get (ospf, area_id, format); @@ -2036,6 +2180,9 @@ DEFUN (no_ospf_area_authentication, struct in_addr area_id; int format; + if (!ospf) + return CMD_SUCCESS; + VTY_GET_OSPF_AREA_ID (area_id, format, argv[0]); area = ospf_area_lookup_by_area_id (ospf, area_id); @@ -2063,6 +2210,9 @@ DEFUN (ospf_abr_type, struct ospf *ospf = vty->index; u_char abr_type = OSPF_ABR_UNKNOWN; + if (!ospf) + return CMD_SUCCESS; + if (strncmp (argv[0], "c", 1) == 0) abr_type = OSPF_ABR_CISCO; else if (strncmp (argv[0], "i", 1) == 0) @@ -2097,6 +2247,9 @@ DEFUN (no_ospf_abr_type, struct ospf *ospf = vty->index; u_char abr_type = OSPF_ABR_UNKNOWN; + if (!ospf) + return CMD_SUCCESS; + if (strncmp (argv[0], "c", 1) == 0) abr_type = OSPF_ABR_CISCO; else if (strncmp (argv[0], "i", 1) == 0) @@ -2125,6 +2278,9 @@ DEFUN (ospf_log_adjacency_changes, { struct ospf *ospf = vty->index; + if (!ospf) + return CMD_SUCCESS; + SET_FLAG(ospf->config, OSPF_LOG_ADJACENCY_CHANGES); return CMD_SUCCESS; } @@ -2137,6 +2293,9 @@ DEFUN (ospf_log_adjacency_changes_detail, { struct ospf *ospf = vty->index; + if (!ospf) + return CMD_SUCCESS; + SET_FLAG(ospf->config, OSPF_LOG_ADJACENCY_CHANGES); SET_FLAG(ospf->config, OSPF_LOG_ADJACENCY_DETAIL); return CMD_SUCCESS; @@ -2150,6 +2309,9 @@ DEFUN (no_ospf_log_adjacency_changes, { struct ospf *ospf = vty->index; + if (!ospf) + return CMD_SUCCESS; + UNSET_FLAG(ospf->config, OSPF_LOG_ADJACENCY_DETAIL); UNSET_FLAG(ospf->config, OSPF_LOG_ADJACENCY_CHANGES); return CMD_SUCCESS; @@ -2164,6 +2326,9 @@ DEFUN (no_ospf_log_adjacency_changes_detail, { struct ospf *ospf = vty->index; + if (!ospf) + return CMD_SUCCESS; + UNSET_FLAG(ospf->config, OSPF_LOG_ADJACENCY_DETAIL); return CMD_SUCCESS; } @@ -2176,6 +2341,9 @@ DEFUN (ospf_compatible_rfc1583, { struct ospf *ospf = vty->index; + if (!ospf) + return CMD_SUCCESS; + if (!CHECK_FLAG (ospf->config, OSPF_RFC1583_COMPATIBLE)) { SET_FLAG (ospf->config, OSPF_RFC1583_COMPATIBLE); @@ -2193,6 +2361,9 @@ DEFUN (no_ospf_compatible_rfc1583, { struct ospf *ospf = vty->index; + if (!ospf) + return CMD_SUCCESS; + if (CHECK_FLAG (ospf->config, OSPF_RFC1583_COMPATIBLE)) { UNSET_FLAG (ospf->config, OSPF_RFC1583_COMPATIBLE); @@ -2221,6 +2392,9 @@ ospf_timers_spf_set (struct vty *vty, unsigned int delay, { struct ospf *ospf = vty->index; + if (!ospf) + return CMD_SUCCESS; + ospf->spf_delay = delay; ospf->spf_holdtime = hold; ospf->spf_max_holdtime = max; @@ -2316,6 +2490,9 @@ DEFUN (ospf_neighbor, unsigned int priority = OSPF_NEIGHBOR_PRIORITY_DEFAULT; unsigned int interval = OSPF_POLL_INTERVAL_DEFAULT; + if (!ospf) + return CMD_SUCCESS; + VTY_GET_IPV4_ADDRESS ("neighbor address", nbr_addr, argv[0]); if (argc > 1) @@ -2364,6 +2541,9 @@ DEFUN (ospf_neighbor_poll_interval, unsigned int priority = OSPF_NEIGHBOR_PRIORITY_DEFAULT; unsigned int interval = OSPF_POLL_INTERVAL_DEFAULT; + if (!ospf) + return CMD_SUCCESS; + VTY_GET_IPV4_ADDRESS ("neighbor address", nbr_addr, argv[0]); if (argc > 1) @@ -2401,6 +2581,9 @@ DEFUN (no_ospf_neighbor, struct ospf *ospf = vty->index; struct in_addr nbr_addr; + if (!ospf) + return CMD_SUCCESS; + VTY_GET_IPV4_ADDRESS ("neighbor address", nbr_addr, argv[0]); (void)ospf_nbr_nbma_unset (ospf, nbr_addr); @@ -2447,6 +2630,9 @@ DEFUN (ospf_refresh_timer, ospf_refresh_timer_cmd, struct ospf *ospf = vty->index; unsigned int interval; + if (!ospf) + return CMD_SUCCESS; + VTY_GET_INTEGER_RANGE ("refresh timer", interval, argv[0], 10, 1800); interval = (interval / 10) * 10; @@ -2464,6 +2650,9 @@ DEFUN (no_ospf_refresh_timer, no_ospf_refresh_timer_val_cmd, struct ospf *ospf = vty->index; unsigned int interval; + if (!ospf) + return CMD_SUCCESS; + if (argc == 1) { VTY_GET_INTEGER_RANGE ("refresh timer", interval, argv[0], 10, 1800); @@ -2496,6 +2685,9 @@ DEFUN (ospf_auto_cost_reference_bandwidth, struct listnode *node; struct interface *ifp; + if (!ospf) + return CMD_SUCCESS; + refbw = strtol (argv[0], NULL, 10); if (refbw < 1 || refbw > 4294967) { @@ -2525,6 +2717,9 @@ DEFUN (no_ospf_auto_cost_reference_bandwidth, struct listnode *node, *nnode; struct interface *ifp; + if (!ospf) + return CMD_SUCCESS; + if (ospf->ref_bandwidth == OSPF_DEFAULT_REF_BANDWIDTH) return CMD_SUCCESS; @@ -2548,6 +2743,9 @@ DEFUN (ospf_write_multiplier, struct ospf *ospf = vty->index; u_int32_t write_oi_count; + if (!ospf) + return CMD_SUCCESS; + write_oi_count = strtol (argv[0], NULL, 10); if (write_oi_count < 1 || write_oi_count > 100) { @@ -2574,6 +2772,9 @@ DEFUN (no_ospf_write_multiplier, { struct ospf *ospf = vty->index; + if (!ospf) + return CMD_SUCCESS; + ospf->write_oi_count = OSPF_WRITE_INTERFACE_COUNT_DEFAULT; return CMD_SUCCESS; } @@ -2726,32 +2927,23 @@ show_ip_ospf_area (struct vty *vty, struct ospf_area *area) vty_out (vty, "%s", VTY_NEWLINE); } -DEFUN (show_ip_ospf, - show_ip_ospf_cmd, - "show ip ospf", - SHOW_STR - IP_STR - "OSPF information\n") +static int +show_ip_ospf_common (struct vty *vty, struct ospf *ospf) { struct listnode *node, *nnode; struct ospf_area * area; - struct ospf *ospf; struct timeval result; char timebuf[OSPF_TIME_DUMP_SIZE]; - /* Check OSPF is enable. */ - ospf = ospf_lookup (); - if (ospf == NULL) - { - vty_out (vty, " OSPF Routing Process not enabled%s", VTY_NEWLINE); - return CMD_SUCCESS; - } + if (ospf->instance) + vty_out (vty, "%sOSPF Instance: %d%s%s", VTY_NEWLINE, ospf->instance, + VTY_NEWLINE, VTY_NEWLINE); /* Show Router ID. */ vty_out (vty, " OSPF Routing Process, Router ID: %s%s", inet_ntoa (ospf->router_id), VTY_NEWLINE); - + /* Graceful shutdown */ if (ospf->t_deferred_shutdown) vty_out (vty, " Deferred shutdown in progress, %s remaining%s", @@ -2860,6 +3052,40 @@ DEFUN (show_ip_ospf, return CMD_SUCCESS; } +DEFUN (show_ip_ospf, + show_ip_ospf_cmd, + "show ip ospf", + SHOW_STR + IP_STR + "OSPF information\n") + +{ + struct ospf *ospf; + + if ((ospf = ospf_lookup()) == NULL) + return CMD_SUCCESS; + + return (show_ip_ospf_common(vty, ospf)); +} + +DEFUN (show_ip_ospf_instance, + show_ip_ospf_instance_cmd, + "show ip ospf <1-65535>", + SHOW_STR + IP_STR + "OSPF information\n" + "Instance ID\n") +{ + struct ospf *ospf; + u_short instance = 0; + + VTY_GET_INTEGER ("Instance", instance, argv[0]); + if ((ospf = ospf_lookup_instance (instance)) == NULL) + return CMD_SUCCESS; + + return (show_ip_ospf_common(vty, ospf)); +} + static void show_ip_ospf_interface_sub (struct vty *vty, struct ospf *ospf, @@ -3026,42 +3252,75 @@ show_ip_ospf_interface_sub (struct vty *vty, struct ospf *ospf, } } -DEFUN (show_ip_ospf_interface, - show_ip_ospf_interface_cmd, - "show ip ospf interface [INTERFACE]", - SHOW_STR - IP_STR - "OSPF information\n" - "Interface information\n" - "Interface name\n") +static int +show_ip_ospf_interface_common (struct vty *vty, struct ospf *ospf, int arg_base, + int argc, const char **argv) { struct interface *ifp; - struct ospf *ospf; struct listnode *node; - ospf = ospf_lookup (); - if (ospf == NULL) + if (ospf->instance) + vty_out (vty, "%sOSPF Instance: %d%s%s", VTY_NEWLINE, ospf->instance, + VTY_NEWLINE, VTY_NEWLINE); + + if (argc == arg_base + 0) { - vty_out (vty, "OSPF Routing Process not enabled%s", VTY_NEWLINE); - return CMD_SUCCESS; + /* Show All Interfaces. */ + for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp)) + if (ospf_oi_count(ifp)) + show_ip_ospf_interface_sub (vty, ospf, ifp); } - - /* Show All Interfaces. */ - if (argc == 0) - for (ALL_LIST_ELEMENTS_RO (iflist, node, ifp)) - show_ip_ospf_interface_sub (vty, ospf, ifp); - /* Interface name is specified. */ else { - if ((ifp = if_lookup_by_name (argv[0])) == NULL) + /* Interface name is specified. */ + if ((ifp = if_lookup_by_name (argv[arg_base + 0])) == NULL) vty_out (vty, "No such interface name%s", VTY_NEWLINE); else show_ip_ospf_interface_sub (vty, ospf, ifp); } + vty_out (vty, "%s", VTY_NEWLINE); + return CMD_SUCCESS; } +DEFUN (show_ip_ospf_interface, + show_ip_ospf_interface_cmd, + "show ip ospf interface [INTERFACE]", + SHOW_STR + IP_STR + "OSPF information\n" + "Interface information\n" + "Interface name\n") +{ + struct ospf *ospf; + + if ((ospf = ospf_lookup()) == NULL) + return CMD_SUCCESS; + + return show_ip_ospf_interface_common(vty, ospf, 0, argc, argv); +} + +DEFUN (show_ip_ospf_instance_interface, + show_ip_ospf_instance_interface_cmd, + "show ip ospf <1-65535> interface [INTERFACE]", + SHOW_STR + IP_STR + "OSPF information\n" + "Instance ID\n" + "Interface information\n" + "Interface name\n") +{ + struct ospf *ospf; + u_short instance = 0; + + VTY_GET_INTEGER ("Instance", instance, argv[0]); + if ((ospf = ospf_lookup_instance (instance)) == NULL) + return CMD_SUCCESS; + + return show_ip_ospf_interface_common(vty, ospf, 1, argc, argv); +} + static void show_ip_ospf_neighbour_header (struct vty *vty) { @@ -3110,54 +3369,72 @@ show_ip_ospf_neighbor_sub (struct vty *vty, struct ospf_interface *oi) } } -DEFUN (show_ip_ospf_neighbor, - show_ip_ospf_neighbor_cmd, - "show ip ospf neighbor", - SHOW_STR - IP_STR - "OSPF information\n" - "Neighbor list\n") +static int +show_ip_ospf_neighbor_common (struct vty *vty, struct ospf *ospf) { - struct ospf *ospf; struct ospf_interface *oi; struct listnode *node; - ospf = ospf_lookup (); - if (ospf == NULL) - { - vty_out (vty, " OSPF Routing Process not enabled%s", VTY_NEWLINE); - return CMD_SUCCESS; - } + if (ospf->instance) + vty_out (vty, "%sOSPF Instance: %d%s", VTY_NEWLINE, ospf->instance, VTY_NEWLINE); show_ip_ospf_neighbour_header (vty); for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi)) show_ip_ospf_neighbor_sub (vty, oi); + vty_out (vty, "%s", VTY_NEWLINE); + return CMD_SUCCESS; } -DEFUN (show_ip_ospf_neighbor_all, - show_ip_ospf_neighbor_all_cmd, - "show ip ospf neighbor all", +DEFUN (show_ip_ospf_neighbor, + show_ip_ospf_neighbor_cmd, + "show ip ospf neighbor", SHOW_STR IP_STR "OSPF information\n" - "Neighbor list\n" - "include down status neighbor\n") + "Neighbor list\n") +{ + struct ospf *ospf; + + if ((ospf = ospf_lookup()) == NULL) + return CMD_SUCCESS; + + return show_ip_ospf_neighbor_common(vty, ospf); +} + + +DEFUN (show_ip_ospf_instance_neighbor, + show_ip_ospf_instance_neighbor_cmd, + "show ip ospf <1-65535> neighbor", + SHOW_STR + IP_STR + "OSPF information\n" + "Instance ID\n" + "Neighbor list\n") +{ + struct ospf *ospf; + u_short instance = 0; + + VTY_GET_INTEGER ("Instance", instance, argv[0]); + if ((ospf = ospf_lookup_instance(instance)) == NULL) + return CMD_SUCCESS; + + return show_ip_ospf_neighbor_common(vty, ospf); +} + +static int +show_ip_ospf_neighbor_all_common (struct vty *vty, struct ospf *ospf) { - struct ospf *ospf = ospf_lookup (); struct listnode *node; struct ospf_interface *oi; - if (ospf == NULL) - { - vty_out (vty, " OSPF Routing Process not enabled%s", VTY_NEWLINE); - return CMD_SUCCESS; - } - + if (ospf->instance) + vty_out (vty, "%sOSPF Instance: %d%s", VTY_NEWLINE, ospf->instance, VTY_NEWLINE); + show_ip_ospf_neighbour_header (vty); - + for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi)) { struct listnode *nbr_node; @@ -3180,35 +3457,64 @@ DEFUN (show_ip_ospf_neighbor_all, } } + vty_out (vty, "%s", VTY_NEWLINE); + return CMD_SUCCESS; } -DEFUN (show_ip_ospf_neighbor_int, - show_ip_ospf_neighbor_int_cmd, - "show ip ospf neighbor IFNAME", +DEFUN (show_ip_ospf_neighbor_all, + show_ip_ospf_neighbor_all_cmd, + "show ip ospf neighbor all", SHOW_STR IP_STR "OSPF information\n" "Neighbor list\n" - "Interface name\n") + "include down status neighbor\n") +{ + struct ospf *ospf; + + if ((ospf = ospf_lookup()) == NULL) + return CMD_SUCCESS; + + return show_ip_ospf_neighbor_all_common(vty, ospf); +} + +DEFUN (show_ip_ospf_instance_neighbor_all, + show_ip_ospf_instance_neighbor_all_cmd, + "show ip ospf <1-65535> neighbor all", + SHOW_STR + IP_STR + "OSPF information\n" + "Instance ID\n" + "Neighbor list\n" + "include down status neighbor\n") { struct ospf *ospf; + u_short instance = 0; + + VTY_GET_INTEGER ("Instance", instance, argv[0]); + if ((ospf = ospf_lookup_instance(instance)) == NULL) + return CMD_SUCCESS; + + return show_ip_ospf_neighbor_all_common(vty, ospf); +} + +static int +show_ip_ospf_neighbor_int_common (struct vty *vty, struct ospf *ospf, int arg_base, + const char **argv) +{ struct interface *ifp; struct route_node *rn; - - ifp = if_lookup_by_name (argv[0]); + + if (ospf->instance) + vty_out (vty, "%sOSPF Instance: %d%s", VTY_NEWLINE, ospf->instance, VTY_NEWLINE); + + ifp = if_lookup_by_name (argv[arg_base + 0]); if (!ifp) { vty_out (vty, "No such interface.%s", VTY_NEWLINE); return CMD_WARNING; } - - ospf = ospf_lookup (); - if (ospf == NULL) - { - vty_out (vty, " OSPF Routing Process not enabled%s", VTY_NEWLINE); - return CMD_SUCCESS; - } show_ip_ospf_neighbour_header (vty); @@ -3225,6 +3531,43 @@ DEFUN (show_ip_ospf_neighbor_int, return CMD_SUCCESS; } +DEFUN (show_ip_ospf_neighbor_int, + show_ip_ospf_neighbor_int_cmd, + "show ip ospf neighbor IFNAME", + SHOW_STR + IP_STR + "OSPF information\n" + "Neighbor list\n" + "Interface name\n") +{ + struct ospf *ospf; + + if ((ospf = ospf_lookup()) == NULL) + return CMD_SUCCESS; + + return show_ip_ospf_neighbor_int_common(vty, ospf, 0, argv); +} + +DEFUN (show_ip_ospf_instance_neighbor_int, + show_ip_ospf_instance_neighbor_int_cmd, + "show ip ospf <1-65535> neighbor IFNAME", + SHOW_STR + IP_STR + "OSPF information\n" + "Instance ID\n" + "Neighbor list\n" + "Interface name\n") +{ + struct ospf *ospf; + u_short instance = 0; + + VTY_GET_INTEGER ("Instance", instance, argv[0]); + if ((ospf = ospf_lookup_instance(instance)) == NULL) + return CMD_SUCCESS; + + return show_ip_ospf_neighbor_int_common(vty, ospf, 1, argv); +} + static void show_ip_ospf_nbr_nbma_detail_sub (struct vty *vty, struct ospf_interface *oi, struct ospf_nbr_nbma *nbr_nbma) @@ -3335,36 +3678,27 @@ show_ip_ospf_neighbor_detail_sub (struct vty *vty, struct ospf_interface *oi, nbr->t_ls_upd != NULL ? "on" : "off", VTY_NEWLINE, VTY_NEWLINE); } -DEFUN (show_ip_ospf_neighbor_id, - show_ip_ospf_neighbor_id_cmd, - "show ip ospf neighbor A.B.C.D", - SHOW_STR - IP_STR - "OSPF information\n" - "Neighbor list\n" - "Neighbor ID\n") +static int +show_ip_ospf_neighbor_id_common (struct vty *vty, struct ospf *ospf, + int arg_base, const char **argv) { - struct ospf *ospf; struct listnode *node; struct ospf_neighbor *nbr; struct ospf_interface *oi; struct in_addr router_id; int ret; - ret = inet_aton (argv[0], &router_id); + if (ospf->instance) + vty_out (vty, "%sOSPF Instance: %d%s%s", VTY_NEWLINE, ospf->instance, + VTY_NEWLINE, VTY_NEWLINE); + + ret = inet_aton (argv[arg_base + 0], &router_id); if (!ret) { vty_out (vty, "Please specify Neighbor ID by A.B.C.D%s", VTY_NEWLINE); return CMD_WARNING; } - ospf = ospf_lookup (); - if (ospf == NULL) - { - vty_out (vty, " OSPF Routing Process not enabled%s", VTY_NEWLINE); - return CMD_SUCCESS; - } - for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi)) if ((nbr = ospf_nbr_lookup_by_routerid (oi->nbrs, &router_id))) show_ip_ospf_neighbor_detail_sub (vty, oi, nbr); @@ -3372,25 +3706,52 @@ DEFUN (show_ip_ospf_neighbor_id, return CMD_SUCCESS; } -DEFUN (show_ip_ospf_neighbor_detail, - show_ip_ospf_neighbor_detail_cmd, - "show ip ospf neighbor detail", +DEFUN (show_ip_ospf_neighbor_id, + show_ip_ospf_neighbor_id_cmd, + "show ip ospf neighbor A.B.C.D", SHOW_STR IP_STR "OSPF information\n" "Neighbor list\n" - "detail of all neighbors\n") + "Neighbor ID\n") { struct ospf *ospf; + + if ((ospf = ospf_lookup()) == NULL) + return CMD_SUCCESS; + + return show_ip_ospf_neighbor_id_common(vty, ospf, 0, argv); +} + +DEFUN (show_ip_ospf_instance_neighbor_id, + show_ip_ospf_instance_neighbor_id_cmd, + "show ip ospf <1-65535> neighbor A.B.C.D", + SHOW_STR + IP_STR + "OSPF information\n" + "Instance ID\n" + "Neighbor list\n" + "Neighbor ID\n") +{ + struct ospf *ospf; + u_short instance = 0; + + VTY_GET_INTEGER ("Instance", instance, argv[0]); + if ((ospf = ospf_lookup_instance(instance)) == NULL) + return CMD_SUCCESS; + + return show_ip_ospf_neighbor_id_common(vty, ospf, 1, argv); +} + +static int +show_ip_ospf_neighbor_detail_common (struct vty *vty, struct ospf *ospf) +{ struct ospf_interface *oi; struct listnode *node; - ospf = ospf_lookup (); - if (ospf == NULL) - { - vty_out (vty, " OSPF Routing Process not enabled%s", VTY_NEWLINE); - return CMD_SUCCESS; - } + if (ospf->instance) + vty_out (vty, "%sOSPF Instance: %d%s%s", VTY_NEWLINE, ospf->instance, + VTY_NEWLINE, VTY_NEWLINE); for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi)) { @@ -3407,26 +3768,52 @@ DEFUN (show_ip_ospf_neighbor_detail, return CMD_SUCCESS; } -DEFUN (show_ip_ospf_neighbor_detail_all, - show_ip_ospf_neighbor_detail_all_cmd, - "show ip ospf neighbor detail all", +DEFUN (show_ip_ospf_neighbor_detail, + show_ip_ospf_neighbor_detail_cmd, + "show ip ospf neighbor detail", SHOW_STR IP_STR "OSPF information\n" "Neighbor list\n" - "detail of all neighbors\n" - "include down status neighbor\n") + "detail of all neighbors\n") +{ + struct ospf *ospf; + + if ((ospf = ospf_lookup()) == NULL) + return CMD_SUCCESS; + + return show_ip_ospf_neighbor_detail_common(vty, ospf); +} + +DEFUN (show_ip_ospf_instance_neighbor_detail, + show_ip_ospf_instance_neighbor_detail_cmd, + "show ip ospf <1-65535> neighbor detail", + SHOW_STR + IP_STR + "OSPF information\n" + "Instance ID\n" + "Neighbor list\n" + "detail of all neighbors\n") { struct ospf *ospf; + u_short instance = 0; + + VTY_GET_INTEGER ("Instance", instance, argv[0]); + if ((ospf = ospf_lookup_instance (instance)) == NULL) + return CMD_SUCCESS; + + return show_ip_ospf_neighbor_detail_common(vty, ospf); +} + +static int +show_ip_ospf_neighbor_detail_all_common (struct vty *vty, struct ospf *ospf) +{ struct listnode *node; struct ospf_interface *oi; - ospf = ospf_lookup (); - if (ospf == NULL) - { - vty_out (vty, " OSPF Routing Process not enabled%s", VTY_NEWLINE); - return CMD_SUCCESS; - } + if (ospf->instance) + vty_out (vty, "%sOSPF Instance: %d%s%s", VTY_NEWLINE, ospf->instance, + VTY_NEWLINE, VTY_NEWLINE); for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi)) { @@ -3454,37 +3841,65 @@ DEFUN (show_ip_ospf_neighbor_detail_all, return CMD_SUCCESS; } -DEFUN (show_ip_ospf_neighbor_int_detail, - show_ip_ospf_neighbor_int_detail_cmd, - "show ip ospf neighbor IFNAME detail", +DEFUN (show_ip_ospf_neighbor_detail_all, + show_ip_ospf_neighbor_detail_all_cmd, + "show ip ospf neighbor detail all", SHOW_STR IP_STR "OSPF information\n" "Neighbor list\n" - "Interface name\n" - "detail of all neighbors") + "detail of all neighbors\n" + "include down status neighbor\n") { struct ospf *ospf; + + if ((ospf = ospf_lookup()) == NULL) + return CMD_SUCCESS; + + return show_ip_ospf_neighbor_detail_all_common(vty, ospf); +} + +DEFUN (show_ip_ospf_instance_neighbor_detail_all, + show_ip_ospf_instance_neighbor_detail_all_cmd, + "show ip ospf <1-65535> neighbor detail all", + SHOW_STR + IP_STR + "OSPF information\n" + "Instance ID\n" + "Neighbor list\n" + "detail of all neighbors\n" + "include down status neighbor\n") +{ + struct ospf *ospf; + u_short instance = 0; + + VTY_GET_INTEGER ("Instance", instance, argv[0]); + if ((ospf = ospf_lookup_instance(instance)) == NULL) + return CMD_SUCCESS; + + return show_ip_ospf_neighbor_detail_all_common(vty, ospf); +} + +static int +show_ip_ospf_neighbor_int_detail_common (struct vty *vty, struct ospf *ospf, + int arg_base, const char **argv) +{ struct ospf_interface *oi; struct interface *ifp; struct route_node *rn, *nrn; struct ospf_neighbor *nbr; - ifp = if_lookup_by_name (argv[0]); + if (ospf->instance) + vty_out (vty, "%sOSPF Instance: %d%s%s", VTY_NEWLINE, ospf->instance, + VTY_NEWLINE, VTY_NEWLINE); + + ifp = if_lookup_by_name (argv[arg_base + 0]); if (!ifp) { vty_out (vty, "No such interface.%s", VTY_NEWLINE); return CMD_WARNING; } - ospf = ospf_lookup (); - if (ospf == NULL) - { - vty_out (vty, " OSPF Routing Process not enabled%s", VTY_NEWLINE); - return CMD_SUCCESS; - } - - for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn)) if ((oi = rn->info)) for (nrn = route_top (oi->nbrs); nrn; nrn = route_next (nrn)) @@ -3496,6 +3911,44 @@ DEFUN (show_ip_ospf_neighbor_int_detail, return CMD_SUCCESS; } +DEFUN (show_ip_ospf_neighbor_int_detail, + show_ip_ospf_neighbor_int_detail_cmd, + "show ip ospf neighbor IFNAME detail", + SHOW_STR + IP_STR + "OSPF information\n" + "Neighbor list\n" + "Interface name\n" + "detail of all neighbors") +{ + struct ospf *ospf; + + if ((ospf = ospf_lookup()) == NULL) + return CMD_SUCCESS; + + return show_ip_ospf_neighbor_int_detail_common(vty, ospf, 0, argv); +} + +DEFUN (show_ip_ospf_instance_neighbor_int_detail, + show_ip_ospf_instance_neighbor_int_detail_cmd, + "show ip ospf <1-65535> neighbor IFNAME detail", + SHOW_STR + IP_STR + "OSPF information\n" + "Instance ID\n" + "Neighbor list\n" + "Interface name\n" + "detail of all neighbors") +{ + struct ospf *ospf; + u_short instance = 0; + + VTY_GET_INTEGER ("Instance", instance, argv[0]); + if ((ospf = ospf_lookup_instance(instance)) == NULL) + return CMD_SUCCESS; + + return show_ip_ospf_neighbor_int_detail_common(vty, ospf, 1, argv); +} /* Show functions */ static int @@ -4154,89 +4607,81 @@ show_ip_ospf_database_maxage (struct vty *vty, struct ospf *ospf) OSPF_LSA_TYPE_OPAQUE_AREA_DESC \ OSPF_LSA_TYPE_OPAQUE_AS_DESC -DEFUN (show_ip_ospf_database, - show_ip_ospf_database_cmd, - "show ip ospf database", - SHOW_STR - IP_STR - "OSPF information\n" - "Database summary\n") +static int +show_ip_ospf_database_common (struct vty *vty, struct ospf *ospf, + int arg_base, int argc, const char **argv) { - struct ospf *ospf; int type, ret; struct in_addr id, adv_router; - ospf = ospf_lookup (); - if (ospf == NULL) - { - vty_out (vty, " OSPF Routing Process not enabled%s", VTY_NEWLINE); - return CMD_SUCCESS; - } + if (ospf->instance) + vty_out (vty, "%sOSPF Instance: %d%s", VTY_NEWLINE, ospf->instance, + VTY_NEWLINE); vty_out (vty, "%s OSPF Router with ID (%s)%s%s", VTY_NEWLINE, inet_ntoa (ospf->router_id), VTY_NEWLINE, VTY_NEWLINE); /* Show all LSA. */ - if (argc == 0) + if (argc == arg_base + 0) { show_ip_ospf_database_summary (vty, ospf, 0); return CMD_SUCCESS; } /* Set database type to show. */ - if (strncmp (argv[0], "r", 1) == 0) + if (strncmp (argv[arg_base + 0], "r", 1) == 0) type = OSPF_ROUTER_LSA; - else if (strncmp (argv[0], "ne", 2) == 0) + else if (strncmp (argv[arg_base + 0], "ne", 2) == 0) type = OSPF_NETWORK_LSA; - else if (strncmp (argv[0], "ns", 2) == 0) + else if (strncmp (argv[arg_base + 0], "ns", 2) == 0) type = OSPF_AS_NSSA_LSA; - else if (strncmp (argv[0], "su", 2) == 0) + else if (strncmp (argv[arg_base + 0], "su", 2) == 0) type = OSPF_SUMMARY_LSA; - else if (strncmp (argv[0], "a", 1) == 0) + else if (strncmp (argv[arg_base + 0], "a", 1) == 0) type = OSPF_ASBR_SUMMARY_LSA; - else if (strncmp (argv[0], "e", 1) == 0) + else if (strncmp (argv[arg_base + 0], "e", 1) == 0) type = OSPF_AS_EXTERNAL_LSA; - else if (strncmp (argv[0], "se", 2) == 0) + else if (strncmp (argv[arg_base + 0], "se", 2) == 0) { show_ip_ospf_database_summary (vty, ospf, 1); return CMD_SUCCESS; } - else if (strncmp (argv[0], "m", 1) == 0) + else if (strncmp (argv[arg_base + 0], "m", 1) == 0) { show_ip_ospf_database_maxage (vty, ospf); return CMD_SUCCESS; } #ifdef HAVE_OPAQUE_LSA - else if (strncmp (argv[0], "opaque-l", 8) == 0) + else if (strncmp (argv[arg_base + 0], "opaque-l", 8) == 0) type = OSPF_OPAQUE_LINK_LSA; - else if (strncmp (argv[0], "opaque-ar", 9) == 0) + else if (strncmp (argv[arg_base + 0], "opaque-ar", 9) == 0) type = OSPF_OPAQUE_AREA_LSA; - else if (strncmp (argv[0], "opaque-as", 9) == 0) + else if (strncmp (argv[arg_base + 0], "opaque-as", 9) == 0) type = OSPF_OPAQUE_AS_LSA; #endif /* HAVE_OPAQUE_LSA */ else return CMD_WARNING; /* `show ip ospf database LSA'. */ - if (argc == 1) + if (argc == arg_base + 1) show_lsa_detail (vty, ospf, type, NULL, NULL); - else if (argc >= 2) + else if (argc >= arg_base + 2) { - ret = inet_aton (argv[1], &id); + ret = inet_aton (argv[arg_base + 1], &id); if (!ret) return CMD_WARNING; /* `show ip ospf database LSA ID'. */ - if (argc == 2) + if (argc == arg_base + 2) show_lsa_detail (vty, ospf, type, &id, NULL); /* `show ip ospf database LSA ID adv-router ADV_ROUTER'. */ - else if (argc == 3) + else if (argc == arg_base + 3) { - if (strncmp (argv[2], "s", 1) == 0) + if (strncmp (argv[arg_base + 2], "s", 1) == 0) adv_router = ospf->router_id; else { - ret = inet_aton (argv[2], &adv_router); + ret = inet_aton (argv[arg_base + 2], &adv_router); if (!ret) return CMD_WARNING; } @@ -4247,6 +4692,22 @@ DEFUN (show_ip_ospf_database, return CMD_SUCCESS; } +DEFUN (show_ip_ospf_database, + show_ip_ospf_database_cmd, + "show ip ospf database", + SHOW_STR + IP_STR + "OSPF information\n" + "Database summary\n") +{ + struct ospf *ospf; + + if ((ospf = ospf_lookup()) == NULL) + return CMD_SUCCESS; + + return (show_ip_ospf_database_common(vty, ospf, 0, argc, argv)); +} + ALIAS (show_ip_ospf_database, show_ip_ospf_database_type_cmd, "show ip ospf database (" OSPF_LSA_TYPES_CMD_STR "|max-age|self-originate)", @@ -4292,64 +4753,123 @@ ALIAS (show_ip_ospf_database, "Self-originated link states\n" "\n") -DEFUN (show_ip_ospf_database_type_adv_router, - show_ip_ospf_database_type_adv_router_cmd, - "show ip ospf database (" OSPF_LSA_TYPES_CMD_STR ") adv-router A.B.C.D", +DEFUN (show_ip_ospf_instance_database, + show_ip_ospf_instance_database_cmd, + "show ip ospf <1-65535> database", SHOW_STR IP_STR "OSPF information\n" + "Instance ID\n" + "Database summary\n") +{ + struct ospf *ospf; + u_short instance = 0; + + VTY_GET_INTEGER ("Instance", instance, argv[0]); + + if ((ospf = ospf_lookup_instance (instance)) == NULL) + return CMD_SUCCESS; + + return (show_ip_ospf_database_common(vty, ospf, 1, argc, argv)); +} + +ALIAS (show_ip_ospf_instance_database, + show_ip_ospf_instance_database_type_cmd, + "show ip ospf <1-65535> database (" OSPF_LSA_TYPES_CMD_STR "|max-age|self-originate)", + SHOW_STR + IP_STR + "OSPF information\n" + "Instance ID\n" + "Database summary\n" + OSPF_LSA_TYPES_DESC + "LSAs in MaxAge list\n" + "Self-originated link states\n") + +ALIAS (show_ip_ospf_instance_database, + show_ip_ospf_instance_database_type_id_cmd, + "show ip ospf <1-65535> database (" OSPF_LSA_TYPES_CMD_STR ") A.B.C.D", + SHOW_STR + IP_STR + "OSPF information\n" + "Instance ID\n" "Database summary\n" OSPF_LSA_TYPES_DESC + "Link State ID (as an IP address)\n") + +ALIAS (show_ip_ospf_instance_database, + show_ip_ospf_instance_database_type_id_adv_router_cmd, + "show ip ospf <1-65535> database (" OSPF_LSA_TYPES_CMD_STR ") A.B.C.D adv-router A.B.C.D", + SHOW_STR + IP_STR + "OSPF information\n" + "Instance ID\n" + "Database summary\n" + OSPF_LSA_TYPES_DESC + "Link State ID (as an IP address)\n" "Advertising Router link states\n" "Advertising Router (as an IP address)\n") + +ALIAS (show_ip_ospf_instance_database, + show_ip_ospf_instance_database_type_id_self_cmd, + "show ip ospf <1-65535> database (" OSPF_LSA_TYPES_CMD_STR ") A.B.C.D (self-originate|)", + SHOW_STR + IP_STR + "OSPF information\n" + "Instance ID\n" + "Database summary\n" + OSPF_LSA_TYPES_DESC + "Link State ID (as an IP address)\n" + "Self-originated link states\n" + "\n") + + +static int +show_ip_ospf_database_type_adv_router_common (struct vty *vty, struct ospf *ospf, + int arg_base, int argc, const char **argv) { - struct ospf *ospf; int type, ret; struct in_addr adv_router; - ospf = ospf_lookup (); - if (ospf == NULL) - { - vty_out (vty, " OSPF Routing Process not enabled%s", VTY_NEWLINE); - return CMD_SUCCESS; - } + if (ospf->instance) + vty_out (vty, "%sOSPF Instance: %d%s", VTY_NEWLINE, ospf->instance, + VTY_NEWLINE); vty_out (vty, "%s OSPF Router with ID (%s)%s%s", VTY_NEWLINE, inet_ntoa (ospf->router_id), VTY_NEWLINE, VTY_NEWLINE); - if (argc != 2) + if (argc != arg_base + 2) return CMD_WARNING; /* Set database type to show. */ - if (strncmp (argv[0], "r", 1) == 0) + if (strncmp (argv[arg_base + 0], "r", 1) == 0) type = OSPF_ROUTER_LSA; - else if (strncmp (argv[0], "ne", 2) == 0) + else if (strncmp (argv[arg_base + 0], "ne", 2) == 0) type = OSPF_NETWORK_LSA; - else if (strncmp (argv[0], "ns", 2) == 0) + else if (strncmp (argv[arg_base + 0], "ns", 2) == 0) type = OSPF_AS_NSSA_LSA; - else if (strncmp (argv[0], "s", 1) == 0) + else if (strncmp (argv[arg_base + 0], "s", 1) == 0) type = OSPF_SUMMARY_LSA; - else if (strncmp (argv[0], "a", 1) == 0) + else if (strncmp (argv[arg_base + 0], "a", 1) == 0) type = OSPF_ASBR_SUMMARY_LSA; - else if (strncmp (argv[0], "e", 1) == 0) + else if (strncmp (argv[arg_base + 0], "e", 1) == 0) type = OSPF_AS_EXTERNAL_LSA; #ifdef HAVE_OPAQUE_LSA - else if (strncmp (argv[0], "opaque-l", 8) == 0) + else if (strncmp (argv[arg_base + 0], "opaque-l", 8) == 0) type = OSPF_OPAQUE_LINK_LSA; - else if (strncmp (argv[0], "opaque-ar", 9) == 0) + else if (strncmp (argv[arg_base + 0], "opaque-ar", 9) == 0) type = OSPF_OPAQUE_AREA_LSA; - else if (strncmp (argv[0], "opaque-as", 9) == 0) + else if (strncmp (argv[arg_base + 0], "opaque-as", 9) == 0) type = OSPF_OPAQUE_AS_LSA; #endif /* HAVE_OPAQUE_LSA */ else return CMD_WARNING; /* `show ip ospf database LSA adv-router ADV_ROUTER'. */ - if (strncmp (argv[1], "s", 1) == 0) + if (strncmp (argv[arg_base + 1], "s", 1) == 0) adv_router = ospf->router_id; else { - ret = inet_aton (argv[1], &adv_router); + ret = inet_aton (argv[arg_base + 1], &adv_router); if (!ret) return CMD_WARNING; } @@ -4359,6 +4879,25 @@ DEFUN (show_ip_ospf_database_type_adv_router, return CMD_SUCCESS; } +DEFUN (show_ip_ospf_database_type_adv_router, + show_ip_ospf_database_type_adv_router_cmd, + "show ip ospf database (" OSPF_LSA_TYPES_CMD_STR ") adv-router A.B.C.D", + SHOW_STR + IP_STR + "OSPF information\n" + "Database summary\n" + OSPF_LSA_TYPES_DESC + "Advertising Router link states\n" + "Advertising Router (as an IP address)\n") +{ + struct ospf *ospf; + + if ((ospf = ospf_lookup()) == NULL) + return CMD_SUCCESS; + + return (show_ip_ospf_database_type_adv_router_common(vty, ospf, 0, argc, argv)); +} + ALIAS (show_ip_ospf_database_type_adv_router, show_ip_ospf_database_type_self_cmd, "show ip ospf database (" OSPF_LSA_TYPES_CMD_STR ") (self-originate|)", @@ -4369,6 +4908,39 @@ ALIAS (show_ip_ospf_database_type_adv_router, OSPF_LSA_TYPES_DESC "Self-originated link states\n") +DEFUN (show_ip_ospf_instance_database_type_adv_router, + show_ip_ospf_instance_database_type_adv_router_cmd, + "show ip ospf <1-65535> database (" OSPF_LSA_TYPES_CMD_STR ") adv-router A.B.C.D", + SHOW_STR + IP_STR + "OSPF information\n" + "Instance ID\n" + "Database summary\n" + OSPF_LSA_TYPES_DESC + "Advertising Router link states\n" + "Advertising Router (as an IP address)\n") +{ + struct ospf *ospf; + u_short instance = 0; + + VTY_GET_INTEGER ("Instance", instance, argv[0]); + + if ((ospf = ospf_lookup_instance (instance)) == NULL) + return CMD_SUCCESS; + + return (show_ip_ospf_database_type_adv_router_common(vty, ospf, 1, argc, argv)); +} + +ALIAS (show_ip_ospf_instance_database_type_adv_router, + show_ip_ospf_instance_database_type_self_cmd, + "show ip ospf <1-65535> database (" OSPF_LSA_TYPES_CMD_STR ") (self-originate|)", + SHOW_STR + IP_STR + "OSPF information\n" + "Instance ID\n" + "Database summary\n" + OSPF_LSA_TYPES_DESC + "Self-originated link states\n") DEFUN (ip_ospf_authentication_args, ip_ospf_authentication_args_addr_cmd, @@ -5909,15 +6481,25 @@ DEFUN (ip_ospf_area, struct ospf *ospf; struct ospf_if_params *params; struct route_node *rn; + u_short instance = 0; - ospf = ospf_lookup (); + if (argc == 2) + VTY_GET_INTEGER ("Instance", instance, argv[0]); + + ospf = ospf_lookup_instance (instance); if (ospf == NULL) { - vty_out (vty, " OSPF Routing Process not enabled%s", VTY_NEWLINE); + params = IF_DEF_PARAMS (ifp); + if (OSPF_IF_PARAM_CONFIGURED(params, if_area)) + { + ospf_interface_unset (ifp); + ospf = ospf_lookup(); + ospf->if_ospf_cli_count--; + } return CMD_SUCCESS; } - ret = ospf_str2area_id (argv[0], &area_id, &format); + ret = ospf_str2area_id (argv[instance ? 1 : 0], &area_id, &format); if (ret < 0) { vty_out (vty, "Please specify area by A.B.C.D|<0-4294967295>%s", @@ -5952,6 +6534,16 @@ DEFUN (ip_ospf_area, return CMD_SUCCESS; } +ALIAS (ip_ospf_area, + ip_ospf_instance_area_cmd, + "ip ospf <1-65535> area (A.B.C.D|<0-4294967295>)", + "IP Information\n" + "OSPF interface commands\n" + "Instance ID\n" + "Enable OSPF on this interface\n" + "OSPF area ID in IP address format\n" + "OSPF area ID as a decimal value\n") + DEFUN (no_ip_ospf_area, no_ip_ospf_area_cmd, "no ip ospf area", @@ -5963,13 +6555,13 @@ DEFUN (no_ip_ospf_area, struct interface *ifp = vty->index; struct ospf *ospf; struct ospf_if_params *params; + u_short instance = 0; - ospf = ospf_lookup (); - if (ospf == NULL) - { - vty_out (vty, " OSPF Routing Process not enabled%s", VTY_NEWLINE); - return CMD_SUCCESS; - } + if (argc) + VTY_GET_INTEGER ("Instance", instance, argv[0]); + + if ((ospf = ospf_lookup_instance (instance)) == NULL) + return CMD_SUCCESS; params = IF_DEF_PARAMS (ifp); if (!OSPF_IF_PARAM_CONFIGURED(params, if_area)) @@ -5983,6 +6575,15 @@ DEFUN (no_ip_ospf_area, return CMD_SUCCESS; } +ALIAS (no_ip_ospf_area, + no_ip_ospf_instance_area_cmd, + "no ip ospf <1-65535> area", + NO_STR + "IP Information\n" + "OSPF interface commands\n" + "Instance ID\n" + "Disable OSPF on this interface\n") + DEFUN (ospf_redistribute_source, ospf_redistribute_source_cmd, "redistribute " QUAGGA_REDIST_STR_OSPFD @@ -6001,10 +6602,14 @@ DEFUN (ospf_redistribute_source, int source; int type = -1; int metric = -1; + struct ospf_redist *red; if (argc < 4) return CMD_WARNING; /* should not happen */ + if (!ospf) + return CMD_SUCCESS; + /* Get distribute source. */ source = proto_redistnum(AFI_IP, argv[0]); if (source < 0 || source == ZEBRA_ROUTE_OSPF) @@ -6020,12 +6625,14 @@ DEFUN (ospf_redistribute_source, if (!str2metric_type (argv[2], &type)) return CMD_WARNING; + red = ospf_redist_add(ospf, source, 0); + if (argv[3] != NULL) - ospf_routemap_set (ospf, source, argv[3]); + ospf_routemap_set (red, argv[3]); else - ospf_routemap_unset (ospf, source); + ospf_routemap_unset (red); - return ospf_redistribute_set (ospf, source, type, metric); + return ospf_redistribute_set (ospf, source, 0, type, metric); } DEFUN (no_ospf_redistribute_source, @@ -6037,13 +6644,131 @@ DEFUN (no_ospf_redistribute_source, { struct ospf *ospf = vty->index; int source; + struct ospf_redist *red; + if (!ospf) + return CMD_SUCCESS; source = proto_redistnum(AFI_IP, argv[0]); if (source < 0 || source == ZEBRA_ROUTE_OSPF) return CMD_WARNING; - ospf_routemap_unset (ospf, source); - return ospf_redistribute_unset (ospf, source); + red = ospf_redist_lookup(ospf, source, 0); + if (!red) + return CMD_SUCCESS; + + ospf_routemap_unset (red); + return ospf_redistribute_unset (ospf, source, 0); +} + +DEFUN (ospf_redistribute_instance_source, + ospf_redistribute_instance_source_cmd, + "redistribute ospf <1-65535>" + " {metric <0-16777214>|metric-type (1|2)|route-map WORD}", + REDIST_STR + "Open Shortest Path First\n" + "Instance ID\n" + "Metric for redistributed routes\n" + "OSPF default metric\n" + "OSPF exterior metric type for redistributed routes\n" + "Set OSPF External Type 1 metrics\n" + "Set OSPF External Type 2 metrics\n" + "Route map reference\n" + "Pointer to route-map entries\n") +{ + struct ospf *ospf = vty->index; + int source; + int type = -1; + int metric = -1; + u_short instance; + struct ospf_redist *red; + + VTY_GET_INTEGER ("Instance ID", instance, argv[0]); + + if (!ospf) + return CMD_SUCCESS; + + if (!ospf->instance) + { + vty_out (vty, "Instance redistribution in non-instanced OSPF not allowed%s", + VTY_NEWLINE); + return CMD_WARNING; + } + + if (ospf->instance == instance) + { + vty_out (vty, "Same instance OSPF redistribution not allowed%s", + VTY_NEWLINE); + return CMD_WARNING; + } + + source = ZEBRA_ROUTE_OSPF; + + /* Get metric value. */ + if (argv[1] != NULL) + if (!str2metric (argv[1], &metric)) + return CMD_WARNING; + + /* Get metric type. */ + if (argv[2] != NULL) + if (!str2metric_type (argv[2], &type)) + return CMD_WARNING; + + red = ospf_redist_add(ospf, source, instance); + if (argv[3] != NULL) + ospf_routemap_set (red, argv[3]); + else + ospf_routemap_unset (red); + + return ospf_redistribute_set (ospf, source, instance, type, metric); +} + +DEFUN (no_ospf_redistribute_instance_source, + no_ospf_redistribute_instance_source_cmd, + "no redistribute ospf <1-65535>" + " {metric <0-16777214>|metric-type (1|2)|route-map WORD}", + NO_STR + REDIST_STR + "Open Shortest Path First\n" + "Instance ID\n" + "Metric for redistributed routes\n" + "OSPF default metric\n" + "OSPF exterior metric type for redistributed routes\n" + "Set OSPF External Type 1 metrics\n" + "Set OSPF External Type 2 metrics\n" + "Route map reference\n" + "Pointer to route-map entries\n") +{ + struct ospf *ospf = vty->index; + u_int instance; + struct ospf_redist *red; + int source; + + if (!ospf) + return CMD_SUCCESS; + + VTY_GET_INTEGER ("Instance ID", instance, argv[0]); + + if (!ospf->instance) + { + vty_out (vty, "Instance redistribution in non-instanced OSPF not allowed%s", + VTY_NEWLINE); + return CMD_WARNING; + } + + if (ospf->instance == instance) + { + vty_out (vty, "Same instance OSPF redistribution not allowed%s", + VTY_NEWLINE); + return CMD_WARNING; + } + + source = ZEBRA_ROUTE_OSPF; + red = ospf_redist_lookup(ospf, source, instance); + if (!red) + return CMD_SUCCESS; + + ospf_routemap_unset (red); + return ospf_redistribute_unset (ospf, source, instance); } DEFUN (ospf_distribute_list_out, @@ -6057,6 +6782,9 @@ DEFUN (ospf_distribute_list_out, struct ospf *ospf = vty->index; int source; + if (!ospf) + return CMD_SUCCESS; + /* Get distribute source. */ source = proto_redistnum(AFI_IP, argv[1]); if (source < 0 || source == ZEBRA_ROUTE_OSPF) @@ -6077,6 +6805,9 @@ DEFUN (no_ospf_distribute_list_out, struct ospf *ospf = vty->index; int source; + if (!ospf) + return CMD_SUCCESS; + source = proto_redistnum(AFI_IP, argv[1]); if (source < 0 || source == ZEBRA_ROUTE_OSPF) return CMD_WARNING; @@ -6104,6 +6835,10 @@ DEFUN (ospf_default_information_originate, int default_originate = DEFAULT_ORIGINATE_ZEBRA; int type = -1; int metric = -1; + struct ospf_redist *red; + + if (!ospf) + return CMD_SUCCESS; if (argc < 4) return CMD_WARNING; /* this should not happen */ @@ -6112,6 +6847,8 @@ DEFUN (ospf_default_information_originate, if (argv[0] != NULL) default_originate = DEFAULT_ORIGINATE_ALWAYS; + red = ospf_redist_add(ospf, DEFAULT_ROUTE, 0); + /* Get metric value. */ if (argv[1] != NULL) if (!str2metric (argv[1], &metric)) @@ -6123,9 +6860,9 @@ DEFUN (ospf_default_information_originate, return CMD_WARNING; if (argv[3] != NULL) - ospf_routemap_set (ospf, DEFAULT_ROUTE, argv[3]); + ospf_routemap_set (red, argv[3]); else - ospf_routemap_unset (ospf, DEFAULT_ROUTE); + ospf_routemap_unset (red); return ospf_redistribute_default_set (ospf, default_originate, type, metric); @@ -6140,20 +6877,29 @@ DEFUN (no_ospf_default_information_originate, { struct ospf *ospf = vty->index; struct prefix_ipv4 p; + struct ospf_external *ext; + struct ospf_redist *red; + if (!ospf) + return CMD_SUCCESS; + p.family = AF_INET; p.prefix.s_addr = 0; p.prefixlen = 0; ospf_external_lsa_flush (ospf, DEFAULT_ROUTE, &p, 0); - if (EXTERNAL_INFO (DEFAULT_ROUTE)) { - ospf_external_info_delete (DEFAULT_ROUTE, p); - route_table_finish (EXTERNAL_INFO (DEFAULT_ROUTE)); - EXTERNAL_INFO (DEFAULT_ROUTE) = NULL; + if ((ext = ospf_external_lookup(DEFAULT_ROUTE, 0)) && + EXTERNAL_INFO (ext)) { + ospf_external_info_delete (DEFAULT_ROUTE, 0, p); + ospf_external_del (DEFAULT_ROUTE, 0); } - ospf_routemap_unset (ospf, DEFAULT_ROUTE); + red = ospf_redist_lookup(ospf, DEFAULT_ROUTE, 0); + if (!red) + return CMD_SUCCESS; + + ospf_routemap_unset (red); return ospf_redistribute_default_unset (ospf); } @@ -6166,6 +6912,9 @@ DEFUN (ospf_default_metric, struct ospf *ospf = vty->index; int metric = -1; + if (!ospf) + return CMD_SUCCESS; + if (!str2metric (argv[0], &metric)) return CMD_WARNING; @@ -6182,6 +6931,9 @@ DEFUN (no_ospf_default_metric, { struct ospf *ospf = vty->index; + if (!ospf) + return CMD_SUCCESS; + ospf->default_metric = -1; return CMD_SUCCESS; @@ -6202,6 +6954,9 @@ DEFUN (ospf_distance, { struct ospf *ospf = vty->index; + if (!ospf) + return CMD_SUCCESS; + ospf->distance_all = atoi (argv[0]); return CMD_SUCCESS; @@ -6216,6 +6971,9 @@ DEFUN (no_ospf_distance, { struct ospf *ospf = vty->index; + if (!ospf) + return CMD_SUCCESS; + ospf->distance_all = 0; return CMD_SUCCESS; @@ -6237,6 +6995,9 @@ DEFUN (no_ospf_distance_ospf, if (argc < 3) return CMD_WARNING; + if (!ospf) + return CMD_SUCCESS; + if (argv[0] != NULL) ospf->distance_intra = 0; @@ -6303,6 +7064,9 @@ DEFUN (ospf_distance_source, { struct ospf *ospf = vty->index; + if (!ospf) + return CMD_SUCCESS; + ospf_distance_set (vty, ospf, argv[0], argv[1], NULL); return CMD_SUCCESS; @@ -6318,6 +7082,9 @@ DEFUN (no_ospf_distance_source, { struct ospf *ospf = vty->index; + if (!ospf) + return CMD_SUCCESS; + ospf_distance_unset (vty, ospf, argv[0], argv[1], NULL); return CMD_SUCCESS; @@ -6333,6 +7100,9 @@ DEFUN (ospf_distance_source_access_list, { struct ospf *ospf = vty->index; + if (!ospf) + return CMD_SUCCESS; + ospf_distance_set (vty, ospf, argv[0], argv[1], argv[2]); return CMD_SUCCESS; @@ -6349,6 +7119,9 @@ DEFUN (no_ospf_distance_source_access_list, { struct ospf *ospf = vty->index; + if (!ospf) + return CMD_SUCCESS; + ospf_distance_unset (vty, ospf, argv[0], argv[1], argv[2]); return CMD_SUCCESS; @@ -6464,6 +7237,9 @@ DEFUN (ospf_max_metric_router_lsa_admin, struct ospf_area *area; struct ospf *ospf = vty->index; + if (!ospf) + return CMD_SUCCESS; + for (ALL_LIST_ELEMENTS_RO (ospf->areas, ln, area)) { SET_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED); @@ -6490,6 +7266,9 @@ DEFUN (no_ospf_max_metric_router_lsa_admin, struct ospf_area *area; struct ospf *ospf = vty->index; + if (!ospf) + return CMD_SUCCESS; + for (ALL_LIST_ELEMENTS_RO (ospf->areas, ln, area)) { UNSET_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED); @@ -6517,6 +7296,9 @@ DEFUN (ospf_max_metric_router_lsa_startup, unsigned int seconds; struct ospf *ospf = vty->index; + if (!ospf) + return CMD_SUCCESS; + if (argc != 1) { vty_out (vty, "%% Must supply stub-router period"); @@ -6542,6 +7324,9 @@ DEFUN (no_ospf_max_metric_router_lsa_startup, struct ospf_area *area; struct ospf *ospf = vty->index; + if (!ospf) + return CMD_SUCCESS; + ospf->stub_router_startup_time = OSPF_STUB_ROUTER_UNCONFIGURED; for (ALL_LIST_ELEMENTS_RO (ospf->areas, ln, area)) @@ -6570,6 +7355,9 @@ DEFUN (ospf_max_metric_router_lsa_shutdown, unsigned int seconds; struct ospf *ospf = vty->index; + if (!ospf) + return CMD_SUCCESS; + if (argc != 1) { vty_out (vty, "%% Must supply stub-router shutdown period"); @@ -6593,6 +7381,9 @@ DEFUN (no_ospf_max_metric_router_lsa_shutdown, { struct ospf *ospf = vty->index; + if (!ospf) + return CMD_SUCCESS; + ospf->stub_router_shutdown_time = OSPF_STUB_ROUTER_UNCONFIGURED; return CMD_SUCCESS; @@ -6775,21 +7566,12 @@ show_ip_ospf_route_external (struct vty *vty, struct route_table *rt) vty_out (vty, "%s", VTY_NEWLINE); } -DEFUN (show_ip_ospf_border_routers, - show_ip_ospf_border_routers_cmd, - "show ip ospf border-routers", - SHOW_STR - IP_STR - "show all the ABR's and ASBR's\n" - "for this area\n") +static int +show_ip_ospf_border_routers_common (struct vty *vty, struct ospf *ospf) { - struct ospf *ospf; - - if ((ospf = ospf_lookup ()) == NULL) - { - vty_out (vty, " OSPF Routing Process not enabled%s", VTY_NEWLINE); - return CMD_SUCCESS; - } + if (ospf->instance) + vty_out (vty, "%sOSPF Instance: %d%s%s", VTY_NEWLINE, ospf->instance, + VTY_NEWLINE, VTY_NEWLINE); if (ospf->new_table == NULL) { @@ -6803,24 +7585,52 @@ DEFUN (show_ip_ospf_border_routers, /* Show Router routes. */ show_ip_ospf_route_router (vty, ospf->new_rtrs); + vty_out (vty, "%s", VTY_NEWLINE); + return CMD_SUCCESS; } -DEFUN (show_ip_ospf_route, - show_ip_ospf_route_cmd, - "show ip ospf route", +DEFUN (show_ip_ospf_border_routers, + show_ip_ospf_border_routers_cmd, + "show ip ospf border-routers", SHOW_STR IP_STR "OSPF information\n" - "OSPF routing table\n") + "Show all the ABR's and ASBR's\n") { struct ospf *ospf; if ((ospf = ospf_lookup ()) == NULL) - { - vty_out (vty, " OSPF Routing Process not enabled%s", VTY_NEWLINE); - return CMD_SUCCESS; - } + return CMD_SUCCESS; + + return show_ip_ospf_border_routers_common(vty, ospf); +} + +DEFUN (show_ip_ospf_instance_border_routers, + show_ip_ospf_instance_border_routers_cmd, + "show ip ospf <1-65535> border-routers", + SHOW_STR + IP_STR + "OSPF information\n" + "Instance ID\n" + "Show all the ABR's and ASBR's\n") +{ + struct ospf *ospf; + u_short instance = 0; + + VTY_GET_INTEGER ("Instance", instance, argv[0]); + if ((ospf = ospf_lookup_instance (instance)) == NULL) + return CMD_SUCCESS; + + return show_ip_ospf_border_routers_common(vty, ospf); +} + +static int +show_ip_ospf_route_common (struct vty *vty, struct ospf *ospf) +{ + if (ospf->instance) + vty_out (vty, "%sOSPF Instance: %d%s%s", VTY_NEWLINE, ospf->instance, + VTY_NEWLINE, VTY_NEWLINE); if (ospf->new_table == NULL) { @@ -6837,9 +7647,45 @@ DEFUN (show_ip_ospf_route, /* Show AS External routes. */ show_ip_ospf_route_external (vty, ospf->old_external_route); + vty_out (vty, "%s", VTY_NEWLINE); + return CMD_SUCCESS; } +DEFUN (show_ip_ospf_route, + show_ip_ospf_route_cmd, + "show ip ospf route", + SHOW_STR + IP_STR + "OSPF information\n" + "OSPF routing table\n") +{ + struct ospf *ospf; + + if ((ospf = ospf_lookup ()) == NULL) + return CMD_SUCCESS; + + return show_ip_ospf_route_common(vty, ospf); +} + +DEFUN (show_ip_ospf_instance_route, + show_ip_ospf_instance_route_cmd, + "show ip ospf <1-65535> route", + SHOW_STR + IP_STR + "OSPF information\n" + "Instance ID\n" + "OSPF routing table\n") +{ + struct ospf *ospf; + u_short instance = 0; + + VTY_GET_INTEGER ("Instance", instance, argv[0]); + if ((ospf = ospf_lookup_instance (instance)) == NULL) + return CMD_SUCCESS; + + return show_ip_ospf_route_common(vty, ospf); +} const char *ospf_abr_type_str[] = { @@ -6891,6 +7737,7 @@ config_write_interface (struct vty *vty) int write = 0; struct route_node *rn = NULL; struct ospf_if_params *params; + struct ospf *ospf = ospf_lookup(); for (ALL_LIST_ELEMENTS_RO (iflist, n1, ifp)) { @@ -6972,7 +7819,7 @@ config_write_interface (struct vty *vty) for (ALL_LIST_ELEMENTS_RO (params->auth_crypt, n2, ck)) { vty_out (vty, " ip ospf message-digest-key %d md5 %s", - ck->key_id, ck->auth_key); + ck->key_id, ck->auth_key); if (params != IF_DEF_PARAMS (ifp)) vty_out (vty, " %s", inet_ntoa (rn->p.u.prefix4)); vty_out (vty, "%s", VTY_NEWLINE); @@ -7050,8 +7897,12 @@ config_write_interface (struct vty *vty) /* Area print. */ if (OSPF_IF_PARAM_CONFIGURED (params, if_area)) { - vty_out (vty, " ip ospf area %s%s", - inet_ntoa (params->if_area), VTY_NEWLINE); + if (ospf->instance) + vty_out (vty, " ip ospf %d area %s%s", ospf->instance, + inet_ntoa (params->if_area), VTY_NEWLINE); + else + vty_out (vty, " ip ospf area %s%s", + inet_ntoa (params->if_area), VTY_NEWLINE); } @@ -7323,20 +8174,33 @@ config_write_ospf_redistribute (struct vty *vty, struct ospf *ospf) /* redistribute print. */ for (type = 0; type < ZEBRA_ROUTE_MAX; type++) - if (type != zclient->redist_default && zclient->redist[type]) - { - vty_out (vty, " redistribute %s", zebra_route_string(type)); - if (ospf->dmetric[type].value >= 0) - vty_out (vty, " metric %d", ospf->dmetric[type].value); - - if (ospf->dmetric[type].type == EXTERNAL_METRIC_TYPE_1) - vty_out (vty, " metric-type 1"); + { + struct list *red_list; + struct listnode *node; + struct ospf_redist *red; - if (ROUTEMAP_NAME (ospf, type)) - vty_out (vty, " route-map %s", ROUTEMAP_NAME (ospf, type)); - - vty_out (vty, "%s", VTY_NEWLINE); - } + red_list = ospf->redist[type]; + if (!red_list) + continue; + + for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) + { + vty_out (vty, " redistribute %s", zebra_route_string(type)); + if (red->instance) + vty_out (vty, " %d", red->instance); + + if (red->dmetric.value >= 0) + vty_out (vty, " metric %d", red->dmetric.value); + + if (red->dmetric.type == EXTERNAL_METRIC_TYPE_1) + vty_out (vty, " metric-type 1"); + + if (ROUTEMAP_NAME (red)) + vty_out (vty, " route-map %s", ROUTEMAP_NAME (red)); + + vty_out (vty, "%s", VTY_NEWLINE); + } + } return 0; } @@ -7354,6 +8218,7 @@ static int config_write_ospf_distribute (struct vty *vty, struct ospf *ospf) { int type; + struct ospf_redist *red; if (ospf) { @@ -7371,15 +8236,19 @@ config_write_ospf_distribute (struct vty *vty, struct ospf *ospf) if (ospf->default_originate == DEFAULT_ORIGINATE_ALWAYS) vty_out (vty, " always"); - if (ospf->dmetric[DEFAULT_ROUTE].value >= 0) - vty_out (vty, " metric %d", - ospf->dmetric[DEFAULT_ROUTE].value); - if (ospf->dmetric[DEFAULT_ROUTE].type == EXTERNAL_METRIC_TYPE_1) - vty_out (vty, " metric-type 1"); - - if (ROUTEMAP_NAME (ospf, DEFAULT_ROUTE)) - vty_out (vty, " route-map %s", - ROUTEMAP_NAME (ospf, DEFAULT_ROUTE)); + red = ospf_redist_lookup(ospf, DEFAULT_ROUTE, 0); + if (red) + { + if (red->dmetric.value >= 0) + vty_out (vty, " metric %d", + red->dmetric.value); + if (red->dmetric.type == EXTERNAL_METRIC_TYPE_1) + vty_out (vty, " metric-type 1"); + + if (ROUTEMAP_NAME (red)) + vty_out (vty, " route-map %s", + ROUTEMAP_NAME (red)); + } vty_out (vty, "%s", VTY_NEWLINE); } @@ -7439,7 +8308,10 @@ ospf_config_write (struct vty *vty) if (ospf != NULL) { /* `router ospf' print. */ - vty_out (vty, "router ospf%s", VTY_NEWLINE); + if (ospf->instance) + vty_out (vty, "router ospf %d%s", ospf->instance, VTY_NEWLINE); + else + vty_out (vty, "router ospf%s", VTY_NEWLINE); write++; @@ -7570,6 +8442,9 @@ ospf_vty_show_init (void) install_element (VIEW_NODE, &show_ip_ospf_cmd); install_element (ENABLE_NODE, &show_ip_ospf_cmd); + install_element (VIEW_NODE, &show_ip_ospf_instance_cmd); + install_element (ENABLE_NODE, &show_ip_ospf_instance_cmd); + /* "show ip ospf database" commands. */ install_element (VIEW_NODE, &show_ip_ospf_database_type_cmd); install_element (VIEW_NODE, &show_ip_ospf_database_type_id_cmd); @@ -7586,10 +8461,28 @@ ospf_vty_show_init (void) install_element (ENABLE_NODE, &show_ip_ospf_database_type_self_cmd); install_element (ENABLE_NODE, &show_ip_ospf_database_cmd); + install_element (VIEW_NODE, &show_ip_ospf_instance_database_type_cmd); + install_element (VIEW_NODE, &show_ip_ospf_instance_database_type_id_cmd); + install_element (VIEW_NODE, &show_ip_ospf_instance_database_type_id_adv_router_cmd); + install_element (VIEW_NODE, &show_ip_ospf_instance_database_type_adv_router_cmd); + install_element (VIEW_NODE, &show_ip_ospf_instance_database_type_id_self_cmd); + install_element (VIEW_NODE, &show_ip_ospf_instance_database_type_self_cmd); + install_element (VIEW_NODE, &show_ip_ospf_instance_database_cmd); + install_element (ENABLE_NODE, &show_ip_ospf_instance_database_type_cmd); + install_element (ENABLE_NODE, &show_ip_ospf_instance_database_type_id_cmd); + install_element (ENABLE_NODE, &show_ip_ospf_instance_database_type_id_adv_router_cmd); + install_element (ENABLE_NODE, &show_ip_ospf_instance_database_type_adv_router_cmd); + install_element (ENABLE_NODE, &show_ip_ospf_instance_database_type_id_self_cmd); + install_element (ENABLE_NODE, &show_ip_ospf_instance_database_type_self_cmd); + install_element (ENABLE_NODE, &show_ip_ospf_instance_database_cmd); + /* "show ip ospf interface" commands. */ install_element (VIEW_NODE, &show_ip_ospf_interface_cmd); install_element (ENABLE_NODE, &show_ip_ospf_interface_cmd); + install_element (VIEW_NODE, &show_ip_ospf_instance_interface_cmd); + install_element (ENABLE_NODE, &show_ip_ospf_instance_interface_cmd); + /* "show ip ospf neighbor" commands. */ install_element (VIEW_NODE, &show_ip_ospf_neighbor_int_detail_cmd); install_element (VIEW_NODE, &show_ip_ospf_neighbor_int_cmd); @@ -7606,11 +8499,31 @@ ospf_vty_show_init (void) install_element (ENABLE_NODE, &show_ip_ospf_neighbor_cmd); install_element (ENABLE_NODE, &show_ip_ospf_neighbor_all_cmd); + install_element (VIEW_NODE, &show_ip_ospf_instance_neighbor_int_detail_cmd); + install_element (VIEW_NODE, &show_ip_ospf_instance_neighbor_int_cmd); + install_element (VIEW_NODE, &show_ip_ospf_instance_neighbor_id_cmd); + install_element (VIEW_NODE, &show_ip_ospf_instance_neighbor_detail_all_cmd); + install_element (VIEW_NODE, &show_ip_ospf_instance_neighbor_detail_cmd); + install_element (VIEW_NODE, &show_ip_ospf_instance_neighbor_cmd); + install_element (VIEW_NODE, &show_ip_ospf_instance_neighbor_all_cmd); + install_element (ENABLE_NODE, &show_ip_ospf_instance_neighbor_int_detail_cmd); + install_element (ENABLE_NODE, &show_ip_ospf_instance_neighbor_int_cmd); + install_element (ENABLE_NODE, &show_ip_ospf_instance_neighbor_id_cmd); + install_element (ENABLE_NODE, &show_ip_ospf_instance_neighbor_detail_all_cmd); + install_element (ENABLE_NODE, &show_ip_ospf_instance_neighbor_detail_cmd); + install_element (ENABLE_NODE, &show_ip_ospf_instance_neighbor_cmd); + install_element (ENABLE_NODE, &show_ip_ospf_instance_neighbor_all_cmd); + /* "show ip ospf route" commands. */ install_element (VIEW_NODE, &show_ip_ospf_route_cmd); install_element (ENABLE_NODE, &show_ip_ospf_route_cmd); install_element (VIEW_NODE, &show_ip_ospf_border_routers_cmd); install_element (ENABLE_NODE, &show_ip_ospf_border_routers_cmd); + + install_element (VIEW_NODE, &show_ip_ospf_instance_route_cmd); + install_element (ENABLE_NODE, &show_ip_ospf_instance_route_cmd); + install_element (VIEW_NODE, &show_ip_ospf_instance_border_routers_cmd); + install_element (ENABLE_NODE, &show_ip_ospf_instance_border_routers_cmd); } @@ -7708,6 +8621,8 @@ ospf_vty_if_init (void) /* "ip ospf area" commands. */ install_element (INTERFACE_NODE, &ip_ospf_area_cmd); install_element (INTERFACE_NODE, &no_ip_ospf_area_cmd); + install_element (INTERFACE_NODE, &ip_ospf_instance_area_cmd); + install_element (INTERFACE_NODE, &no_ip_ospf_instance_area_cmd); /* These commands are compatibitliy for previous version. */ install_element (INTERFACE_NODE, &ospf_authentication_key_cmd); @@ -7741,6 +8656,8 @@ ospf_vty_zebra_init (void) { install_element (OSPF_NODE, &ospf_redistribute_source_cmd); install_element (OSPF_NODE, &no_ospf_redistribute_source_cmd); + install_element (OSPF_NODE, &ospf_redistribute_instance_source_cmd); + install_element (OSPF_NODE, &no_ospf_redistribute_instance_source_cmd); install_element (OSPF_NODE, &ospf_distribute_list_out_cmd); install_element (OSPF_NODE, &no_ospf_distribute_list_out_cmd); @@ -7828,6 +8745,9 @@ ospf_vty_init (void) install_element (CONFIG_NODE, &router_ospf_cmd); install_element (CONFIG_NODE, &no_router_ospf_cmd); + install_element (CONFIG_NODE, &router_ospf_instance_cmd); + install_element (CONFIG_NODE, &no_router_ospf_instance_cmd); + install_default (OSPF_NODE); /* "ospf router-id" commands. */ diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c index 9a3525379..ad7e98f09 100644 --- a/ospfd/ospf_zebra.c +++ b/ospfd/ospf_zebra.c @@ -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) } } +struct ospf_external * +ospf_external_lookup (u_char type, u_short instance) +{ + 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) +ospf_is_type_redistributed (int type, u_short instance) { - return (DEFAULT_ROUTE_TYPE (type)) ? - zclient->default_information : zclient->redist[type]; + 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) { + struct ospf_redist *red; + ospf->default_originate = originate; - ospf->dmetric[DEFAULT_ROUTE].type = mtype; - ospf->dmetric[DEFAULT_ROUTE].value = mvalue; - if (ospf_is_type_redistributed (DEFAULT_ROUTE)) + 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; diff --git a/ospfd/ospf_zebra.h b/ospfd/ospf_zebra.h index 148f6520f..1cebb3d6d 100644 --- a/ospfd/ospf_zebra.h +++ b/ospfd/ospf_zebra.h @@ -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 */ diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c index a69b5595d..e815c521c 100644 --- a/ospfd/ospfd.c +++ b/ospfd/ospfd.c @@ -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) diff --git a/ospfd/ospfd.h b/ospfd/ospfd.h index 53c4099f2..7cbd85786 100644 --- a/ospfd/ospfd.h +++ b/ospfd/ospfd.h @@ -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 *, diff --git a/ripd/rip_main.c b/ripd/rip_main.c index e81e61b80..dbb9b46fe 100644 --- a/ripd/rip_main.c +++ b/ripd/rip_main.c @@ -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. */ diff --git a/ripd/rip_zebra.c b/ripd/rip_zebra.c index 1f6ef6120..d0ab21d2b 100644 --- a/ripd/rip_zebra.c +++ b/ripd/rip_zebra.c @@ -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; diff --git a/ripngd/ripng_main.c b/ripngd/ripng_main.c index acc980ded..522c48272 100644 --- a/ripngd/ripng_main.c +++ b/ripngd/ripng_main.c @@ -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) diff --git a/ripngd/ripng_zebra.c b/ripngd/ripng_zebra.c index 68f37be32..92c845418 100644 --- a/ripngd/ripng_zebra.c +++ b/ripngd/ripng_zebra.c @@ -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; diff --git a/tests/test-sig.c b/tests/test-sig.c index df023fac6..75e2afceb 100644 --- a/tests/test-sig.c +++ b/tests/test-sig.c @@ -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); diff --git a/vtysh/extract.pl.in b/vtysh/extract.pl.in index 49788363e..2249b4092 100755 --- a/vtysh/extract.pl.in +++ b/vtysh/extract.pl.in @@ -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"; diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c index f6d82972d..2534e8ae1 100644 --- a/vtysh/vtysh.c +++ b/vtysh/vtysh.c @@ -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[] = -{ - { .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}, + char *path; + struct vtysh_client *next; +}; + +struct vtysh_client vtysh_client[] = +{ + { .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 diff --git a/watchquagga/watchquagga.c b/watchquagga/watchquagga.c index c1c889210..ca05361c1 100644 --- a/watchquagga/watchquagga.c +++ b/watchquagga/watchquagga.c @@ -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) diff --git a/zebra/connected.c b/zebra/connected.c index ef1792c2f..0c9221da4 100644 --- a/zebra/connected.c +++ b/zebra/connected.c @@ -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 (); } diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c index 3dbeb98bc..03f3eaeb6 100644 --- a/zebra/kernel_socket.c +++ b/zebra/kernel_socket.c @@ -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 */ diff --git a/zebra/main.c b/zebra/main.c index 13ad08eff..6cff6d45d 100644 --- a/zebra/main.c +++ b/zebra/main.c @@ -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) diff --git a/zebra/redistribute.c b/zebra/redistribute.c index 5c9412c13..b67430d1a 100644 --- a/zebra/redistribute.c +++ b/zebra/redistribute.c @@ -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 diff --git a/zebra/rib.h b/zebra/rib.h index 472bcf1d6..e3c606f42 100644 --- a/zebra/rib.h +++ b/zebra/rib.h @@ -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 *); diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index 5e8eb7b9f..1fa4593f4 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -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 */ diff --git a/zebra/rtread_getmsg.c b/zebra/rtread_getmsg.c index 81bf0de64..17d75b283 100644 --- a/zebra/rtread_getmsg.c +++ b/zebra/rtread_getmsg.c @@ -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); } diff --git a/zebra/rtread_proc.c b/zebra/rtread_proc.c index 07e8491ad..b365d958f 100644 --- a/zebra/rtread_proc.c +++ b/zebra/rtread_proc.c @@ -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); diff --git a/zebra/test_main.c b/zebra/test_main.c index f98bb4199..2d4874b7d 100644 --- a/zebra/test_main.c +++ b/zebra/test_main.c @@ -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) diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index 08f65be10..f55302e13 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -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. */ diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c index 6031da876..a44d19618 100644 --- a/zebra/zebra_vty.c +++ b/zebra/zebra_vty.c @@ -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); diff --git a/zebra/zserv.c b/zebra/zserv.c index d745a43d5..960514319 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -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); diff --git a/zebra/zserv.h b/zebra/zserv.h index 4e42b8586..cb181eebe 100644 --- a/zebra/zserv.h +++ b/zebra/zserv.h @@ -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; |