summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_network.c6
-rw-r--r--bgpd/bgp_route.c19
-rw-r--r--bgpd/bgp_routemap.c49
-rw-r--r--bgpd/bgp_vty.c1
-rw-r--r--bgpd/bgp_zebra.c10
-rw-r--r--doc/routemap.texi20
-rw-r--r--lib/vty.c15
-rw-r--r--lib/zclient.c1
-rw-r--r--pimd/pim_cmd.c13
-rw-r--r--pimd/pim_zebra.c7
-rw-r--r--zebra/rt_netlink.c19
-rw-r--r--zebra/rt_netlink.h1
-rw-r--r--zebra/zebra_mpls.c37
-rw-r--r--zebra/zebra_mpls_netlink.c24
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
diff --git a/lib/vty.c b/lib/vty.c
index 12c3c12394..4026e0cf8a 100644
--- a/lib/vty.c
+++ b/lib/vty.c
@@ -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;
}