json_nexthop_global = json_object_new_object();
}
- if (!json_paths && safi == SAFI_EVPN) {
+ if (!json_paths && path->extra) {
char tag_buf[30];
- bgp_evpn_route2str((struct prefix_evpn *)&bn->p,
- buf2, sizeof(buf2));
- vty_out(vty, " Route %s", buf2);
+ buf2[0] = '\0';
tag_buf[0] = '\0';
if (path->extra && path->extra->num_labels) {
bgp_evpn_label2str(path->extra->label,
path->extra->num_labels, tag_buf,
sizeof(tag_buf));
- vty_out(vty, " VNI %s", tag_buf);
}
- vty_out(vty, "\n");
+ if (safi == SAFI_EVPN) {
+ bgp_evpn_route2str((struct prefix_evpn *)&bn->p,
+ buf2, sizeof(buf2));
+ vty_out(vty, " Route %s", buf2);
+ if (tag_buf[0] != '\0')
+ vty_out(vty, " VNI %s", tag_buf);
+ vty_out(vty, "\n");
+ }
+
if (path->extra && path->extra->parent) {
struct bgp_path_info *parent_ri;
struct bgp_node *rn, *prn;
rn = parent_ri->net;
if (rn && rn->prn) {
prn = rn->prn;
- vty_out(vty, " Imported from %s:%s\n",
- prefix_rd2str(
- (struct prefix_rd *)&prn->p,
- buf1, sizeof(buf1)),
- buf2);
+ prefix_rd2str((struct prefix_rd *)&prn->p,
+ buf1, sizeof(buf1));
+ if (is_pi_family_evpn(parent_ri)) {
+ bgp_evpn_route2str((struct prefix_evpn *)&rn->p,
+ buf2, sizeof(buf2));
+ vty_out(vty, " Imported from %s:%s, VNI %s\n", buf1, buf2, tag_buf);
+ } else
+ vty_out(vty, " Imported from %s:%s\n", buf1, buf2);
}
}
}
if (!yang_dnode_get_bool(dnode, NULL))
vty_out(vty, " no");
- vty_out(vty, "isis bfd\n");
+ vty_out(vty, " isis bfd\n");
}
/*
}
/* Create new interface structure. */
-struct interface *if_create(const char *name, vrf_id_t vrf_id)
+static struct interface *if_create_backend(const char *name, ifindex_t ifindex,
+ vrf_id_t vrf_id)
{
struct vrf *vrf = vrf_get(vrf_id, NULL);
struct interface *ifp;
ifp = XCALLOC(MTYPE_IF, sizeof(struct interface));
- ifp->ifindex = IFINDEX_INTERNAL;
-
- assert(name);
- strlcpy(ifp->name, name, sizeof(ifp->name));
ifp->vrf_id = vrf_id;
- IFNAME_RB_INSERT(vrf, ifp);
+
+ if (name) {
+ strlcpy(ifp->name, name, sizeof(ifp->name));
+ IFNAME_RB_INSERT(vrf, ifp);
+ } else
+ ifp->name[0] = '\0';
+
+ if (ifindex != IFINDEX_INTERNAL)
+ if_set_index(ifp, ifindex);
+ else
+ ifp->ifindex = ifindex; /* doesn't add it to the list */
+
ifp->connected = list_new();
ifp->connected->del = (void (*)(void *))connected_free;
return ifp;
}
+struct interface *if_create(const char *name, vrf_id_t vrf_id)
+{
+ return if_create_backend(name, IFINDEX_INTERNAL, vrf_id);
+}
+
+struct interface *if_create_ifindex(ifindex_t ifindex, vrf_id_t vrf_id)
+{
+ return if_create_backend(NULL, ifindex, vrf_id);
+}
+
/* Create new interface structure. */
void if_update_to_new_vrf(struct interface *ifp, vrf_id_t vrf_id)
{
return NULL;
}
+struct interface *if_lookup_by_index_all_vrf(ifindex_t ifindex)
+{
+ struct vrf *vrf;
+ struct interface *ifp;
+
+ if (ifindex == IFINDEX_INTERNAL)
+ return NULL;
+
+ RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) {
+ ifp = if_lookup_by_index(ifindex, vrf->vrf_id);
+ if (ifp)
+ return ifp;
+ }
+
+ return NULL;
+}
+
/* Lookup interface by IPv4 address. */
struct interface *if_lookup_exact_address(void *src, int family,
vrf_id_t vrf_id)
return NULL;
}
+struct interface *if_get_by_ifindex(ifindex_t ifindex, vrf_id_t vrf_id)
+{
+ struct interface *ifp;
+
+ switch (vrf_get_backend()) {
+ case VRF_BACKEND_UNKNOWN:
+ case VRF_BACKEND_NETNS:
+ ifp = if_lookup_by_index(ifindex, vrf_id);
+ if (ifp)
+ return ifp;
+ return if_create_ifindex(ifindex, vrf_id);
+ case VRF_BACKEND_VRF_LITE:
+ ifp = if_lookup_by_index_all_vrf(ifindex);
+ if (ifp) {
+ if (ifp->vrf_id == vrf_id)
+ return ifp;
+ /* If it came from the kernel or by way of zclient,
+ * believe it and update the ifp accordingly.
+ */
+ if_update_to_new_vrf(ifp, vrf_id);
+ return ifp;
+ }
+ return if_create_ifindex(ifindex, vrf_id);
+ }
+
+ return NULL;
+}
+
void if_set_index(struct interface *ifp, ifindex_t ifindex)
{
struct vrf *vrf;
*/
extern void if_update_to_new_vrf(struct interface *, vrf_id_t vrf_id);
extern struct interface *if_create(const char *name, vrf_id_t vrf_id);
+extern struct interface *if_create_ifindex(ifindex_t ifindex, vrf_id_t vrf_id);
extern struct interface *if_lookup_by_index(ifindex_t, vrf_id_t vrf_id);
+extern struct interface *if_lookup_by_index_all_vrf(ifindex_t);
extern struct interface *if_lookup_exact_address(void *matchaddr, int family,
vrf_id_t vrf_id);
extern struct connected *if_lookup_address(void *matchaddr, int family,
extern struct interface *if_lookup_by_name_all_vrf(const char *ifname);
extern struct interface *if_lookup_by_name(const char *ifname, vrf_id_t vrf_id);
extern struct interface *if_get_by_name(const char *ifname, vrf_id_t vrf_id);
+extern struct interface *if_get_by_ifindex(ifindex_t ifindex, vrf_id_t vrf_id);
extern void if_set_index(struct interface *ifp, ifindex_t ifindex);
/* Delete the interface, but do not free the structure, and leave it in the
char *kind = NULL;
char *desc = NULL;
char *slave_kind = NULL;
- struct zebra_ns *zns;
+ struct zebra_ns *zns = NULL;
vrf_id_t vrf_id = VRF_DEFAULT;
zebra_iftype_t zif_type = ZEBRA_IF_OTHER;
zebra_slave_iftype_t zif_slave_type = ZEBRA_IF_SLAVE_NONE;
ifindex_t link_ifindex = IFINDEX_INTERNAL;
ifindex_t bond_ifindex = IFINDEX_INTERNAL;
struct zebra_if *zif;
+ struct vrf *vrf = NULL;
zns = zebra_ns_lookup(ns_id);
ifi = NLMSG_DATA(h);
if (tb[IFLA_LINK])
link_ifindex = *(ifindex_t *)RTA_DATA(tb[IFLA_LINK]);
- /* Add interface. */
- ifp = if_get_by_name(name, vrf_id);
- set_ifindex(ifp, ifi->ifi_index, zns);
+ vrf = vrf_get(vrf_id, NULL);
+ /* Add interface.
+ * We add by index first because in some cases such as the master
+ * interface, we have the index before we have the name. Fixing
+ * back references on the slave interfaces is painful if not done
+ * this way, i.e. by creating by ifindex.
+ */
+ ifp = if_get_by_ifindex(ifi->ifi_index, vrf_id);
+ set_ifindex(ifp, ifi->ifi_index, zns); /* add it to ns struct */
+ strlcpy(ifp->name, name, sizeof(ifp->name));
+ IFNAME_RB_INSERT(vrf, ifp);
ifp->flags = ifi->ifi_flags & 0x0000fffff;
ifp->mtu6 = ifp->mtu = *(uint32_t *)RTA_DATA(tb[IFLA_MTU]);
ifp->metric = 0;
struct zebra_l2info_brslave *br_slave;
br_slave = &zebra_if->brslave_info;
- if (br_slave->bridge_ifindex != IFINDEX_INTERNAL)
- vty_out(vty, " Master (bridge) ifindex %u\n",
- br_slave->bridge_ifindex);
+ if (br_slave->bridge_ifindex != IFINDEX_INTERNAL) {
+ if (br_slave->br_if)
+ vty_out(vty, " Master interface: %s\n",
+ br_slave->br_if->name);
+ else
+ vty_out(vty, " Master ifindex: %u\n",
+ br_slave->bridge_ifindex);
+ }
}
if (IS_ZEBRA_IF_BOND_SLAVE(ifp)) {
struct zebra_l2info_bondslave *bond_slave;
bond_slave = &zebra_if->bondslave_info;
- if (bond_slave->bond_ifindex != IFINDEX_INTERNAL)
- vty_out(vty, " Master (bond) ifindex %u\n",
- bond_slave->bond_ifindex);
+ if (bond_slave->bond_ifindex != IFINDEX_INTERNAL) {
+ if (bond_slave->bond_if)
+ vty_out(vty, " Master interface: %s\n",
+ bond_slave->bond_if->name);
+ else
+ vty_out(vty, " Master ifindex: %u\n",
+ bond_slave->bond_ifindex);
+ }
}
if (zebra_if->link_ifindex != IFINDEX_INTERNAL) {
- vty_out(vty, " Link ifindex %u", zebra_if->link_ifindex);
if (zebra_if->link)
- vty_out(vty, "(%s)\n", zebra_if->link->name);
+ vty_out(vty, " Parent interface: %s\n", zebra_if->link->name);
else
- vty_out(vty, "(Unknown)\n");
+ vty_out(vty, " Parent ifindex: %d\n", zebra_if->link_ifindex);
}
if (HAS_LINK_PARAMS(ifp)) {
br_slave->br_if = NULL;
}
-void zebra_l2_map_slave_to_bond(struct zebra_l2info_bondslave *bond_slave)
+void zebra_l2_map_slave_to_bond(struct zebra_l2info_bondslave *bond_slave,
+ vrf_id_t vrf_id)
{
struct interface *bond_if;
/* TODO: Handle change of master */
- bond_if = if_lookup_by_index_per_ns(zebra_ns_lookup(NS_DEFAULT),
- bond_slave->bond_ifindex);
+ bond_if = if_lookup_by_index_all_vrf(bond_slave->bond_ifindex);
if (bond_if)
bond_slave->bond_if = bond_if;
+ else
+ bond_slave->bond_if = if_create_ifindex(bond_slave->bond_ifindex,
+ vrf_id);
}
void zebra_l2_unmap_slave_from_bond(struct zebra_l2info_bondslave *bond_slave)
/* Set up or remove link with master */
if (bond_ifindex != IFINDEX_INTERNAL)
- zebra_l2_map_slave_to_bond(&zif->bondslave_info);
+ zebra_l2_map_slave_to_bond(&zif->bondslave_info, ifp->vrf_id);
else if (old_bond_ifindex != IFINDEX_INTERNAL)
zebra_l2_unmap_slave_from_bond(&zif->bondslave_info);
}
extern void
zebra_l2_unmap_slave_from_bridge(struct zebra_l2info_brslave *br_slave);
extern void
-zebra_l2_map_slave_to_bond(struct zebra_l2info_bondslave *bond_slave);
+zebra_l2_map_slave_to_bond(struct zebra_l2info_bondslave *bond_slave, vrf_id_t);
extern void
zebra_l2_unmap_slave_from_bond(struct zebra_l2info_bondslave *bond_slave);
extern void zebra_l2_bridge_add_update(struct interface *ifp,