summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_mplsvpn.c25
-rw-r--r--bgpd/bgp_vty.c5
-rw-r--r--eigrpd/eigrp_topology.c2
-rw-r--r--isisd/isis_spf.c38
-rw-r--r--lib/command.c7
-rw-r--r--lib/sbuf.c5
-rw-r--r--ospfd/ospfd.c7
-rw-r--r--zebra/if_netlink.c20
-rw-r--r--zebra/kernel_netlink.c1
-rw-r--r--zebra/rt_netlink.c19
-rw-r--r--zebra/rule_netlink.c6
-rw-r--r--zebra/zebra_netns_notify.c4
12 files changed, 102 insertions, 37 deletions
diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c
index 28e8ceb15d..3a854be534 100644
--- a/bgpd/bgp_mplsvpn.c
+++ b/bgpd/bgp_mplsvpn.c
@@ -466,6 +466,7 @@ leak_update(
{
struct prefix *p = &bn->p;
struct bgp_info *bi;
+ struct bgp_info *bi_ultimate;
struct bgp_info *new;
char buf_prefix[PREFIX_STRLEN];
@@ -477,6 +478,26 @@ leak_update(
}
/*
+ * Routes that are redistributed into BGP from zebra do not get
+ * nexthop tracking. However, if those routes are subsequently
+ * imported to other RIBs within BGP, the leaked routes do not
+ * carry the original BGP_ROUTE_REDISTRIBUTE sub_type. Therefore,
+ * in order to determine if the route we are currently leaking
+ * should have nexthop tracking, we must find the ultimate
+ * parent so we can check its sub_type.
+ *
+ * As of now, source_bi may at most be a second-generation route
+ * (only one hop back to ultimate parent for vrf-vpn-vrf scheme).
+ * Using a loop here supports more complex intra-bgp import-export
+ * schemes that could be implemented in the future.
+ *
+ */
+ for (bi_ultimate = source_bi;
+ bi_ultimate->extra && bi_ultimate->extra->parent;
+ bi_ultimate = bi_ultimate->extra->parent)
+ ;
+
+ /*
* match parent
*/
for (bi = bn->info; bi; bi = bi->next) {
@@ -528,7 +549,7 @@ leak_update(
bgp_nexthop = bi->extra->bgp_orig;
/* No nexthop tracking for redistributed routes */
- if (source_bi->sub_type == BGP_ROUTE_REDISTRIBUTE)
+ if (bi_ultimate->sub_type == BGP_ROUTE_REDISTRIBUTE)
nh_valid = 1;
else
/*
@@ -591,7 +612,7 @@ leak_update(
* their originating protocols will do the tracking and
* withdraw those routes if the nexthops become unreachable
*/
- if (source_bi->sub_type == BGP_ROUTE_REDISTRIBUTE)
+ if (bi_ultimate->sub_type == BGP_ROUTE_REDISTRIBUTE)
nh_valid = 1;
else
/*
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index 7b1147b617..3d1fdfd38d 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -6737,6 +6737,11 @@ DEFPY (bgp_imexport_vrf,
safi_t safi;
afi_t afi;
+ if (import_name == NULL) {
+ vty_out(vty, "%% Missing import name\n");
+ return CMD_WARNING;
+ }
+
if (argv_find(argv, argc, "no", &idx))
remove = true;
diff --git a/eigrpd/eigrp_topology.c b/eigrpd/eigrp_topology.c
index 4e26446ebe..8ca0e282a8 100644
--- a/eigrpd/eigrp_topology.c
+++ b/eigrpd/eigrp_topology.c
@@ -448,6 +448,8 @@ void eigrp_topology_update_node_flags(struct eigrp_prefix_entry *dest)
struct eigrp_nexthop_entry *entry;
struct eigrp *eigrp = eigrp_lookup();
+ assert(eigrp);
+
for (ALL_LIST_ELEMENTS_RO(dest->entries, node, entry)) {
if (entry->reported_distance < dest->fdistance) {
// is feasible successor, can be successor
diff --git a/isisd/isis_spf.c b/isisd/isis_spf.c
index a55a0e1902..2e2933db33 100644
--- a/isisd/isis_spf.c
+++ b/isisd/isis_spf.c
@@ -77,14 +77,13 @@ enum vertextype {
/*
* Triple <N, d(N), {Adj(N)}>
*/
+union isis_N {
+ uint8_t id[ISIS_SYS_ID_LEN + 1];
+ struct prefix prefix;
+};
struct isis_vertex {
enum vertextype type;
-
- union {
- uint8_t id[ISIS_SYS_ID_LEN + 1];
- struct prefix prefix;
- } N;
-
+ union isis_N N;
uint32_t d_N; /* d(N) Distance from this IS */
uint16_t depth; /* The depth in the imaginary tree */
struct list *Adj_N; /* {Adj(N)} next hop or neighbor list */
@@ -407,28 +406,28 @@ static const char *vid2string(struct isis_vertex *vertex, char *buff, int size)
return "UNKNOWN";
}
-static void isis_vertex_id_init(struct isis_vertex *vertex, void *id,
+static void isis_vertex_id_init(struct isis_vertex *vertex, union isis_N *n,
enum vertextype vtype)
{
vertex->type = vtype;
if (VTYPE_IS(vtype) || VTYPE_ES(vtype)) {
- memcpy(vertex->N.id, (uint8_t *)id, ISIS_SYS_ID_LEN + 1);
+ memcpy(vertex->N.id, n->id, ISIS_SYS_ID_LEN + 1);
} else if (VTYPE_IP(vtype)) {
- memcpy(&vertex->N.prefix, (struct prefix *)id,
- sizeof(struct prefix));
+ memcpy(&vertex->N.prefix, &n->prefix, sizeof(struct prefix));
} else {
zlog_err("WTF!");
}
}
-static struct isis_vertex *isis_vertex_new(void *id, enum vertextype vtype)
+static struct isis_vertex *isis_vertex_new(union isis_N *n,
+ enum vertextype vtype)
{
struct isis_vertex *vertex;
vertex = XCALLOC(MTYPE_ISIS_VERTEX, sizeof(struct isis_vertex));
- isis_vertex_id_init(vertex, id, vtype);
+ isis_vertex_id_init(vertex, n, vtype);
vertex->Adj_N = list_new();
vertex->parents = list_new();
@@ -598,17 +597,17 @@ static struct isis_vertex *isis_spf_add_root(struct isis_spftree *spftree,
#ifdef EXTREME_DEBUG
char buff[PREFIX2STR_BUFFER];
#endif /* EXTREME_DEBUG */
- uint8_t id[ISIS_SYS_ID_LEN + 1];
+ union isis_N n;
- memcpy(id, sysid, ISIS_SYS_ID_LEN);
- LSP_PSEUDO_ID(id) = 0;
+ memcpy(n.id, sysid, ISIS_SYS_ID_LEN);
+ LSP_PSEUDO_ID(n.id) = 0;
lsp = isis_root_system_lsp(spftree->area, spftree->level, sysid);
if (lsp == NULL)
zlog_warn("ISIS-Spf: could not find own l%d LSP!",
spftree->level);
- vertex = isis_vertex_new(id,
+ vertex = isis_vertex_new(&n,
spftree->area->oldmetric
? VTYPE_NONPSEUDO_IS
: VTYPE_NONPSEUDO_TE_IS);
@@ -625,11 +624,12 @@ static struct isis_vertex *isis_spf_add_root(struct isis_spftree *spftree,
}
static struct isis_vertex *isis_find_vertex(struct isis_vertex_queue *queue,
- void *id, enum vertextype vtype)
+ union isis_N *n,
+ enum vertextype vtype)
{
struct isis_vertex querier;
- isis_vertex_id_init(&querier, id, vtype);
+ isis_vertex_id_init(&querier, n, vtype);
return hash_lookup(queue->hash, &querier);
}
@@ -1212,7 +1212,7 @@ static void add_to_paths(struct isis_spftree *spftree,
{
char buff[PREFIX2STR_BUFFER];
- if (isis_find_vertex(&spftree->paths, vertex->N.id, vertex->type))
+ if (isis_find_vertex(&spftree->paths, &vertex->N, vertex->type))
return;
isis_vertex_queue_append(&spftree->paths, vertex);
diff --git a/lib/command.c b/lib/command.c
index 4d88f295a3..0bf856f248 100644
--- a/lib/command.c
+++ b/lib/command.c
@@ -261,8 +261,11 @@ void print_version(const char *progname)
char *argv_concat(struct cmd_token **argv, int argc, int shift)
{
- int cnt = argc - shift;
- const char *argstr[cnt];
+ int cnt = MAX(argc - shift, 0);
+ const char *argstr[cnt + 1];
+
+ if (!cnt)
+ return NULL;
for (int i = 0; i < cnt; i++)
argstr[i] = argv[i + shift]->arg;
diff --git a/lib/sbuf.c b/lib/sbuf.c
index 37c1e5283d..03a2be3e09 100644
--- a/lib/sbuf.c
+++ b/lib/sbuf.c
@@ -63,13 +63,12 @@ void sbuf_push(struct sbuf *buf, int indent, const char *format, ...)
int written;
if (!buf->fixed) {
- char dummy;
int written1, written2;
size_t new_size;
- written1 = snprintf(&dummy, 0, "%*s", indent, "");
+ written1 = indent;
va_start(args, format);
- written2 = vsnprintf(&dummy, 0, format, args);
+ written2 = vsnprintf(NULL, 0, format, args);
va_end(args);
new_size = buf->size;
diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c
index 4cf38439c6..f315421843 100644
--- a/ospfd/ospfd.c
+++ b/ospfd/ospfd.c
@@ -243,13 +243,14 @@ static struct ospf *ospf_new(unsigned short instance, const char *name)
zlog_debug(
"%s: Create new ospf instance with vrf_name %s vrf_id %u",
__PRETTY_FUNCTION__, name, new->vrf_id);
- if (vrf)
- ospf_vrf_link(new, vrf);
} else {
new->vrf_id = VRF_DEFAULT;
vrf = vrf_lookup_by_id(VRF_DEFAULT);
- ospf_vrf_link(new, vrf);
}
+
+ if (vrf)
+ ospf_vrf_link(new, vrf);
+
ospf_zebra_vrf_register(new);
new->abr_type = OSPF_ABR_DEFAULT;
diff --git a/zebra/if_netlink.c b/zebra/if_netlink.c
index e6d324ab6a..5c84219418 100644
--- a/zebra/if_netlink.c
+++ b/zebra/if_netlink.c
@@ -586,8 +586,13 @@ static int netlink_interface(struct nlmsghdr *h, ns_id_t ns_id, int startup)
return 0;
len = h->nlmsg_len - NLMSG_LENGTH(sizeof(struct ifinfomsg));
- if (len < 0)
+ if (len < 0) {
+ zlog_err("%s: Message received from netlink is of a broken size: %d %zu",
+ __PRETTY_FUNCTION__,
+ h->nlmsg_len,
+ (size_t)NLMSG_LENGTH(sizeof(struct ifinfomsg)));
return -1;
+ }
/* We are interested in some AF_BRIDGE notifications. */
if (ifi->ifi_family == AF_BRIDGE)
@@ -893,8 +898,13 @@ int netlink_interface_addr(struct nlmsghdr *h, ns_id_t ns_id, int startup)
return 0;
len = h->nlmsg_len - NLMSG_LENGTH(sizeof(struct ifaddrmsg));
- if (len < 0)
+ if (len < 0) {
+ zlog_err("%s: Message received from netlink is of a broken size: %d %zu",
+ __PRETTY_FUNCTION__,
+ h->nlmsg_len,
+ (size_t)NLMSG_LENGTH(sizeof(struct ifaddrmsg)));
return -1;
+ }
memset(tb, 0, sizeof tb);
netlink_parse_rtattr(tb, IFA_MAX, IFA_RTA(ifa), len);
@@ -1105,8 +1115,12 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
}
len = h->nlmsg_len - NLMSG_LENGTH(sizeof(struct ifinfomsg));
- if (len < 0)
+ if (len < 0) {
+ zlog_err("%s: Message received from netlink is of a broken size %d %zu",
+ __PRETTY_FUNCTION__, h->nlmsg_len,
+ (size_t)NLMSG_LENGTH(sizeof(struct ifinfomsg)));
return -1;
+ }
/* We are interested in some AF_BRIDGE notifications. */
if (ifi->ifi_family == AF_BRIDGE)
diff --git a/zebra/kernel_netlink.c b/zebra/kernel_netlink.c
index 6d164cfdab..7334c8094a 100644
--- a/zebra/kernel_netlink.c
+++ b/zebra/kernel_netlink.c
@@ -772,6 +772,7 @@ int netlink_parse_info(int (*filter)(struct nlmsghdr *, ns_id_t, int),
error = (*filter)(h, zns->ns_id, startup);
if (error < 0) {
zlog_err("%s filter function error", nl->name);
+ zlog_backtrace(LOG_ERR);
ret = error;
}
}
diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c
index a5f288f541..9033491549 100644
--- a/zebra/rt_netlink.c
+++ b/zebra/rt_netlink.c
@@ -295,8 +295,12 @@ static int netlink_route_change_read_unicast(struct nlmsghdr *h, ns_id_t ns_id,
}
len = h->nlmsg_len - NLMSG_LENGTH(sizeof(struct rtmsg));
- if (len < 0)
+ if (len < 0) {
+ zlog_err("%s: Message received from netlink is of a broken size %d %zu",
+ __PRETTY_FUNCTION__, h->nlmsg_len,
+ (size_t)NLMSG_LENGTH(sizeof(struct rtmsg)));
return -1;
+ }
memset(tb, 0, sizeof tb);
netlink_parse_rtattr(tb, RTA_MAX, RTM_RTA(rtm), len);
@@ -747,8 +751,13 @@ int netlink_route_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
return 0;
len = h->nlmsg_len - NLMSG_LENGTH(sizeof(struct rtmsg));
- if (len < 0)
+ if (len < 0) {
+ zlog_err("%s: Message received from netlink is of a broken size: %d %zu",
+ __PRETTY_FUNCTION__,
+ h->nlmsg_len,
+ (size_t)NLMSG_LENGTH(sizeof(struct rtmsg)));
return -1;
+ }
if (rtm->rtm_type == RTN_MULTICAST)
netlink_route_change_read_multicast(h, ns_id, startup);
@@ -2356,8 +2365,12 @@ int netlink_neigh_change(struct nlmsghdr *h, ns_id_t ns_id)
/* Length validity. */
len = h->nlmsg_len - NLMSG_LENGTH(sizeof(struct ndmsg));
- if (len < 0)
+ if (len < 0) {
+ zlog_err("%s: Message received from netlink is of a broken size %d %zu",
+ __PRETTY_FUNCTION__, h->nlmsg_len,
+ (size_t)NLMSG_LENGTH(sizeof(struct ndmsg)));
return -1;
+ }
/* Is this a notification for the MAC FDB or IP neighbor table? */
ndm = NLMSG_DATA(h);
diff --git a/zebra/rule_netlink.c b/zebra/rule_netlink.c
index bcffdf4722..c7a8517e17 100644
--- a/zebra/rule_netlink.c
+++ b/zebra/rule_netlink.c
@@ -196,8 +196,12 @@ int netlink_rule_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
return 0;
len = h->nlmsg_len - NLMSG_LENGTH(sizeof(struct fib_rule_hdr));
- if (len < 0)
+ if (len < 0) {
+ zlog_err("%s: Message received from netlink is of a broken size: %d %zu",
+ __PRETTY_FUNCTION__, h->nlmsg_len,
+ (size_t)NLMSG_LENGTH(sizeof(struct fib_rule_hdr)));
return -1;
+ }
frh = NLMSG_DATA(h);
if (frh->family != AF_INET && frh->family != AF_INET6)
diff --git a/zebra/zebra_netns_notify.c b/zebra/zebra_netns_notify.c
index 5feb87b59d..a391f8343f 100644
--- a/zebra/zebra_netns_notify.c
+++ b/zebra/zebra_netns_notify.c
@@ -212,7 +212,9 @@ static int zebra_ns_notify_read(struct thread *t)
continue;
if (event->mask & IN_DELETE)
return zebra_ns_delete(event->name);
- if (&event->name[event->len] >= &buf[sizeof(buf)]) {
+
+ if (offsetof(struct inotify_event, name) + event->len
+ >= sizeof(buf)) {
zlog_err("NS notify read: buffer underflow");
break;
}