diff options
| -rw-r--r-- | bgpd/bgp_network.c | 6 | ||||
| -rw-r--r-- | bgpd/bgp_route.c | 19 | ||||
| -rw-r--r-- | bgpd/bgp_routemap.c | 49 | ||||
| -rw-r--r-- | bgpd/bgp_vty.c | 1 | ||||
| -rw-r--r-- | bgpd/bgp_zebra.c | 10 | ||||
| -rw-r--r-- | doc/routemap.texi | 20 | ||||
| -rw-r--r-- | lib/vty.c | 15 | ||||
| -rw-r--r-- | lib/zclient.c | 1 | ||||
| -rw-r--r-- | pimd/pim_cmd.c | 13 | ||||
| -rw-r--r-- | pimd/pim_zebra.c | 7 | ||||
| -rw-r--r-- | zebra/rt_netlink.c | 19 | ||||
| -rw-r--r-- | zebra/rt_netlink.h | 1 | ||||
| -rw-r--r-- | zebra/zebra_mpls.c | 37 | ||||
| -rw-r--r-- | zebra/zebra_mpls_netlink.c | 24 |
14 files changed, 152 insertions, 70 deletions
diff --git a/bgpd/bgp_network.c b/bgpd/bgp_network.c index 101e0e62bb..0d7680ea51 100644 --- a/bgpd/bgp_network.c +++ b/bgpd/bgp_network.c @@ -740,8 +740,10 @@ int bgp_socket(unsigned short port, const char *address) } freeaddrinfo(ainfo_save); if (count == 0) { - zlog_err("%s: no usable addresses", __func__); - return -1; + zlog_err("%s: no usable addresses please check other programs usage of specified port %d", + __func__, port); + zlog_err("%s: Program cannot continue", __func__); + exit(-1); } return 0; diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index af71088b7d..6230560997 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -8158,8 +8158,8 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi, if (use_json && header) { vty_out(vty, - "{ \"vrfId\": %d, \"vrfName\": \"%s\", \"tableVersion\": %" PRId64 - ", \"routerId\": \"%s\", \"routes\": { ", + "{\n \"vrfId\": %d,\n \"vrfName\": \"%s\",\n \"tableVersion\": %" PRId64 + ",\n \"routerId\": \"%s\",\n \"routes\": { ", bgp->vrf_id == VRF_UNKNOWN ? -1 : bgp->vrf_id, bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT ? "Default" : bgp->name, @@ -8378,7 +8378,7 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi, p->prefixlen); vty_out(vty, "\"%s\": ", buf2); vty_out(vty, "%s", - json_object_to_json_string(json_paths)); + json_object_to_json_string_ext(json_paths, JSON_C_TO_STRING_PRETTY)); json_object_free(json_paths); first = 0; } @@ -9434,8 +9434,8 @@ static struct peer *peer_lookup_in_view(struct vty *vty, struct bgp *bgp, "malformedAddressOrName", ip_str); vty_out(vty, "%s\n", - json_object_to_json_string( - json_no)); + json_object_to_json_string_ext( + json_no, JSON_C_TO_STRING_PRETTY)); json_object_free(json_no); } else vty_out(vty, @@ -9456,7 +9456,8 @@ static struct peer *peer_lookup_in_view(struct vty *vty, struct bgp *bgp, json_object_string_add(json_no, "warning", "No such neighbor"); vty_out(vty, "%s\n", - json_object_to_json_string(json_no)); + json_object_to_json_string_ext(json_no, + JSON_C_TO_STRING_PRETTY)); json_object_free(json_no); } else vty_out(vty, "No such neighbor\n"); @@ -9865,7 +9866,8 @@ static int bgp_peer_counts(struct vty *vty, struct peer *peer, afi_t afi, json, "recommended", "Please report this bug, with the above command output"); } - vty_out(vty, "%s\n", json_object_to_json_string(json)); + vty_out(vty, "%s\n", json_object_to_json_string_ext(json, + JSON_C_TO_STRING_PRETTY)); json_object_free(json); } else { @@ -10243,7 +10245,8 @@ static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi, output_count); } if (use_json) { - vty_out(vty, "%s\n", json_object_to_json_string(json)); + vty_out(vty, "%s\n", json_object_to_json_string_ext(json, + JSON_C_TO_STRING_PRETTY)); json_object_free(json); } } diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c index 217916239c..f26498fb03 100644 --- a/bgpd/bgp_routemap.c +++ b/bgpd/bgp_routemap.c @@ -222,7 +222,12 @@ static void route_aspath_free(void *rule) aspath_free(aspath); } -/* 'match peer (A.B.C.D|X:X::X:X)' */ +struct bgp_match_peer_compiled { + char *interface; + union sockunion su; +}; + +/* 'match peer (A.B.C.D|X:X::X:X|WORD)' */ /* Compares the peer specified in the 'match peer' clause with the peer received in bgp_info->peer. If it is the same, or if the peer structure @@ -231,6 +236,7 @@ static route_map_result_t route_match_peer(void *rule, struct prefix *prefix, route_map_object_t type, void *object) { + struct bgp_match_peer_compiled *pc; union sockunion *su; union sockunion su_def = { .sin = {.sin_family = AF_INET, .sin_addr.s_addr = INADDR_ANY}}; @@ -239,12 +245,19 @@ static route_map_result_t route_match_peer(void *rule, struct prefix *prefix, struct listnode *node, *nnode; if (type == RMAP_BGP) { - su = rule; + pc = rule; + su = &pc->su; peer = ((struct bgp_info *)object)->peer; - if (!CHECK_FLAG(peer->rmap_type, PEER_RMAP_TYPE_IMPORT) - && !CHECK_FLAG(peer->rmap_type, PEER_RMAP_TYPE_EXPORT)) + if (pc->interface) { + if (!peer->conf_if) + return RMAP_NOMATCH; + + if (strcmp(peer->conf_if, pc->interface) == 0) + return RMAP_MATCH; + return RMAP_NOMATCH; + } /* If su='0.0.0.0' (command 'match peer local'), and it's a NETWORK, @@ -283,23 +296,29 @@ static route_map_result_t route_match_peer(void *rule, struct prefix *prefix, static void *route_match_peer_compile(const char *arg) { - union sockunion *su; + struct bgp_match_peer_compiled *pc; int ret; - su = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, sizeof(union sockunion)); + pc = XMALLOC(MTYPE_ROUTE_MAP_COMPILED, + sizeof(struct bgp_match_peer_compiled)); - ret = str2sockunion(strcmp(arg, "local") ? arg : "0.0.0.0", su); + ret = str2sockunion(strcmp(arg, "local") ? arg : "0.0.0.0", &pc->su); if (ret < 0) { - XFREE(MTYPE_ROUTE_MAP_COMPILED, su); - return NULL; + pc->interface = XSTRDUP(MTYPE_ROUTE_MAP_COMPILED, arg); + return pc; } - return su; + return pc; } /* Free route map's compiled `ip address' value. */ static void route_match_peer_free(void *rule) { + struct bgp_match_peer_compiled *pc = rule; + + if (pc->interface) + XFREE(MTYPE_ROUTE_MAP_COMPILED, pc->interface); + XFREE(MTYPE_ROUTE_MAP_COMPILED, rule); } @@ -3148,11 +3167,12 @@ DEFUN (no_match_evpn_vni, DEFUN (match_peer, match_peer_cmd, - "match peer <A.B.C.D|X:X::X:X>", + "match peer <A.B.C.D|X:X::X:X|WORD>", MATCH_STR "Match peer address\n" "IP address of peer\n" - "IPv6 address of peer\n") + "IPv6 address of peer\n" + "Interface name of peer\n") { int idx_ip = 2; return bgp_route_match_add(vty, "peer", argv[idx_ip]->arg, @@ -3172,13 +3192,14 @@ DEFUN (match_peer_local, DEFUN (no_match_peer, no_match_peer_cmd, - "no match peer [<local|A.B.C.D|X:X::X:X>]", + "no match peer [<local|A.B.C.D|X:X::X:X|WORD>]", NO_STR MATCH_STR "Match peer address\n" "Static or Redistributed routes\n" "IP address of peer\n" - "IPv6 address of peer\n") + "IPv6 address of peer\n" + "Interface name of peer\n") { int idx_peer = 3; diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index 749c9d25d4..18190a4f95 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -11334,6 +11334,7 @@ static void bgp_ac_neighbor(vector comps, struct cmd_token *token) static const struct cmd_variable_handler bgp_var_neighbor[] = { {.varname = "neighbor", .completions = bgp_ac_neighbor}, {.varname = "neighbors", .completions = bgp_ac_neighbor}, + {.varname = "peer", .completions = bgp_ac_neighbor}, {.completions = NULL}}; void bgp_vty_init(void) diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 0d1d768294..bec7050226 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -1338,12 +1338,14 @@ int bgp_redistribute_set(struct bgp *bgp, afi_t afi, int type, u_short instance) vrf_bitmap_set(zclient->redist[afi][type], bgp->vrf_id); } - /* Don't try to register if we're not connected to Zebra or Zebra - * doesn't - * know of this instance. + /* + * Don't try to register if we're not connected to Zebra or Zebra + * doesn't know of this instance. + * + * When we come up later well resend if needed. */ if (!bgp_install_info_to_zebra(bgp)) - return CMD_WARNING_CONFIG_FAILED; + return CMD_SUCCESS; if (BGP_DEBUG(zebra, ZEBRA)) zlog_debug("Tx redistribute add VRF %u afi %d %s %d", diff --git a/doc/routemap.texi b/doc/routemap.texi index 33062a7f61..69c07357e7 100644 --- a/doc/routemap.texi +++ b/doc/routemap.texi @@ -5,8 +5,8 @@ Route maps provide a means to both filter and/or apply actions to route, hence allowing policy to be applied to routes. @menu -* Route Map Command:: -* Route Map Match Command:: +* Route Map Command:: +* Route Map Match Command:: * Route Map Set Command:: * Route Map Call Command:: * Route Map Exit Action Command:: @@ -159,6 +159,22 @@ Matches the specified @var{local-preference}. Matches the specified @var{community_list} @end deffn +@deffn {Route-map Command} {match peer @var{ipv4_addr}} {} +This is a BGP specific match command. Matches the peer ip address +if the neighbor was specified in this manner. +@end deffn + +@deffn {Route-map Command} {match peer @var{ipv6_addr}} {} +This is a BGP specific match command. Matches the peer ipv6 +address if the neighbor was specified in this manner. +@end deffn + +@deffn {Route-map Command} {match peer @var{interface_name}} {} +This is a BGP specific match command. Matches the peer +interface name specified if the neighbor was specified +in this manner. +@end deffn + @node Route Map Set Command @section Route Map Set Command @@ -2279,6 +2279,21 @@ static void vty_read_file(FILE *confp) case CMD_ERR_NO_MATCH: message = "No such command"; break; + case CMD_WARNING: + message = "Command returned Warning"; + break; + case CMD_WARNING_CONFIG_FAILED: + message = "Command returned Warning Config Failed"; + break; + case CMD_ERR_INCOMPLETE: + message = "Command returned Incomplete"; + break; + case CMD_ERR_EXEED_ARGC_MAX: + message = "Command exceeded maximum number of Arguments"; + break; + default: + message = "Command returned unhandled error message"; + break; } nl = strchr(vty->error_buf, '\n'); diff --git a/lib/zclient.c b/lib/zclient.c index d23e5fbd79..8ada2cf978 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -574,7 +574,6 @@ void zclient_init(struct zclient *zclient, int redist_default, /* Set default-information redistribute to zero. */ zclient->default_information = vrf_bitmap_init(); - ; if (zclient_debug) zlog_debug("zclient_start is called"); diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index a9239c2835..10b68ab735 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -4252,11 +4252,16 @@ DEFUN (show_ip_pim_nexthop_lookup, memset(&nexthop, 0, sizeof(nexthop)); if (pim_find_or_track_nexthop(vrf->info, &nht_p, NULL, NULL, &pnc)) - pim_ecmp_nexthop_search(vrf->info, &pnc, &nexthop, &nht_p, &grp, - 0); + result = pim_ecmp_nexthop_search(vrf->info, &pnc, &nexthop, + &nht_p, &grp, 0); else - pim_ecmp_nexthop_lookup(vrf->info, &nexthop, vif_source, &nht_p, - &grp, 0); + result = pim_ecmp_nexthop_lookup(vrf->info, &nexthop, vif_source, + &nht_p, &grp, 0); + + if (!result) { + vty_out(vty, "Nexthop Lookup failed, no usable routes returned.\n"); + return CMD_SUCCESS; + } pim_addr_dump("<grp?>", &grp, grp_str, sizeof(grp_str)); pim_addr_dump("<nexthop?>", &nexthop.mrib_nexthop_addr, diff --git a/pimd/pim_zebra.c b/pimd/pim_zebra.c index bee6521b6c..04466258bb 100644 --- a/pimd/pim_zebra.c +++ b/pimd/pim_zebra.c @@ -599,7 +599,9 @@ void pim_scan_individual_oil(struct channel_oil *c_oil, int in_vif_index) zlog_debug( "%s %s: (S,G)=(%s,%s) input interface changed from %s vif_index=%d to %s vif_index=%d", __FILE__, __PRETTY_FUNCTION__, source_str, group_str, - old_iif->name, c_oil->oil.mfcc_parent, new_iif->name, + (old_iif) ? old_iif->name : "<old_iif?>", + c_oil->oil.mfcc_parent, + (new_iif) ? new_iif->name : "<new_iif?>", input_iface_vif_index); } @@ -618,7 +620,8 @@ void pim_scan_individual_oil(struct channel_oil *c_oil, int in_vif_index) zlog_debug( "%s %s: (S,G)=(%s,%s) new iif loops to existing oif: %s vif_index=%d", __FILE__, __PRETTY_FUNCTION__, source_str, - group_str, new_iif->name, + group_str, + (new_iif) ? new_iif->name : "<new_iif?>", input_iface_vif_index); } } diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index 67abe53c39..e8333ef0cf 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -2474,23 +2474,4 @@ int netlink_mpls_multipath(int cmd, zebra_lsp_t *lsp) return netlink_talk(netlink_talk_filter, &req.n, &zns->netlink_cmd, zns, 0); } - -/* - * Handle failure in LSP install, clear flags for NHLFE. - */ -void clear_nhlfe_installed(zebra_lsp_t *lsp) -{ - zebra_nhlfe_t *nhlfe; - struct nexthop *nexthop; - - for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next) { - nexthop = nhlfe->nexthop; - if (!nexthop) - continue; - - UNSET_FLAG(nhlfe->flags, NHLFE_FLAG_INSTALLED); - UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB); - } -} - #endif /* HAVE_NETLINK */ diff --git a/zebra/rt_netlink.h b/zebra/rt_netlink.h index 980ff915cc..afb03f878d 100644 --- a/zebra/rt_netlink.h +++ b/zebra/rt_netlink.h @@ -54,7 +54,6 @@ void rt_netlink_init(void); -extern void clear_nhlfe_installed(zebra_lsp_t *lsp); extern int netlink_mpls_multipath(int cmd, zebra_lsp_t *lsp); extern int netlink_route_change(struct sockaddr_nl *snl, struct nlmsghdr *h, diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c index 7b87355ed4..3765849adf 100644 --- a/zebra/zebra_mpls.c +++ b/zebra/zebra_mpls.c @@ -130,6 +130,24 @@ static int mpls_processq_init(struct zebra_t *zebra); /* Static functions */ /* + * Handle failure in LSP install, clear flags for NHLFE. + */ +static void clear_nhlfe_installed(zebra_lsp_t *lsp) +{ + zebra_nhlfe_t *nhlfe; + struct nexthop *nexthop; + + for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next) { + nexthop = nhlfe->nexthop; + if (!nexthop) + continue; + + UNSET_FLAG(nhlfe->flags, NHLFE_FLAG_INSTALLED); + UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB); + } +} + +/* * Install label forwarding entry based on labeled-route entry. */ static int lsp_install(struct zebra_vrf *zvrf, mpls_label_t label, @@ -821,11 +839,16 @@ static void lsp_select_best_nhlfe(zebra_lsp_t *lsp) */ static void lsp_uninstall_from_kernel(struct hash_backet *backet, void *ctxt) { + int ret; zebra_lsp_t *lsp; lsp = (zebra_lsp_t *)backet->data; - if (CHECK_FLAG(lsp->flags, LSP_FLAG_INSTALLED)) - kernel_del_lsp(lsp); + if (CHECK_FLAG(lsp->flags, LSP_FLAG_INSTALLED)) { + ret = kernel_del_lsp(lsp); + + if (!ret) + clear_nhlfe_installed(lsp); + } } /* @@ -846,6 +869,7 @@ static void lsp_schedule(struct hash_backet *backet, void *ctxt) */ static wq_item_status lsp_process(struct work_queue *wq, void *data) { + int ret = 1; zebra_lsp_t *lsp; zebra_nhlfe_t *oldbest, *newbest; char buf[BUFSIZ], buf2[BUFSIZ]; @@ -877,20 +901,23 @@ static wq_item_status lsp_process(struct work_queue *wq, void *data) if (!CHECK_FLAG(lsp->flags, LSP_FLAG_INSTALLED)) { /* Not already installed */ if (newbest) { - kernel_add_lsp(lsp); + ret = kernel_add_lsp(lsp); zvrf->lsp_installs++; } } else { /* Installed, may need an update and/or delete. */ if (!newbest) { - kernel_del_lsp(lsp); + ret = kernel_del_lsp(lsp); zvrf->lsp_removals++; } else if (CHECK_FLAG(lsp->flags, LSP_FLAG_CHANGED)) { - kernel_upd_lsp(lsp); + ret = kernel_upd_lsp(lsp); zvrf->lsp_installs++; } } + if (!ret) + clear_nhlfe_installed(lsp); + return WQ_SUCCESS; } diff --git a/zebra/zebra_mpls_netlink.c b/zebra/zebra_mpls_netlink.c index 8b30783a9a..887c685498 100644 --- a/zebra/zebra_mpls_netlink.c +++ b/zebra/zebra_mpls_netlink.c @@ -40,8 +40,6 @@ int kernel_add_lsp(zebra_lsp_t *lsp) ret = netlink_mpls_multipath(RTM_NEWROUTE, lsp); if (!ret) SET_FLAG(lsp->flags, LSP_FLAG_INSTALLED); - else - clear_nhlfe_installed(lsp); return ret; } @@ -60,22 +58,32 @@ int kernel_add_lsp(zebra_lsp_t *lsp) int kernel_upd_lsp(zebra_lsp_t *lsp) { int ret; + zebra_nhlfe_t *nhlfe; + struct nexthop *nexthop; if (!lsp || !lsp->best_nhlfe) // unexpected return -1; UNSET_FLAG(lsp->flags, LSP_FLAG_CHANGED); - /* First issue a DEL and clear the installed flag. */ - netlink_mpls_multipath(RTM_DELROUTE, lsp); - UNSET_FLAG(lsp->flags, LSP_FLAG_INSTALLED); + /* Any NHLFE that was installed but is not selected now needs to + * have its flags updated. + */ + for (nhlfe = lsp->nhlfe_list; nhlfe; nhlfe = nhlfe->next) { + nexthop = nhlfe->nexthop; + if (!nexthop) + continue; + + if (CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_INSTALLED) && + !CHECK_FLAG(nhlfe->flags, NHLFE_FLAG_SELECTED)) { + UNSET_FLAG(nhlfe->flags, NHLFE_FLAG_INSTALLED); + UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB); + } + } - /* Then issue an ADD. */ ret = netlink_mpls_multipath(RTM_NEWROUTE, lsp); if (!ret) SET_FLAG(lsp->flags, LSP_FLAG_INSTALLED); - else - clear_nhlfe_installed(lsp); return ret; } |
