diff options
Diffstat (limited to 'zebra/interface.c')
| -rw-r--r-- | zebra/interface.c | 271 |
1 files changed, 180 insertions, 91 deletions
diff --git a/zebra/interface.c b/zebra/interface.c index 21eeb20543..8b5dbabb92 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -584,7 +584,7 @@ void if_add_update(struct interface *ifp) { struct zebra_if *if_data; struct zebra_ns *zns; - struct zebra_vrf *zvrf = vrf_info_lookup(ifp->vrf_id); + struct zebra_vrf *zvrf = ifp->vrf->info; /* case interface populate before vrf enabled */ if (zvrf->zns) @@ -611,8 +611,8 @@ void if_add_update(struct interface *ifp) if (IS_ZEBRA_DEBUG_KERNEL) { zlog_debug( "interface %s vrf %s(%u) index %d is shutdown. Won't wake it up.", - ifp->name, VRF_LOGNAME(zvrf->vrf), - ifp->vrf_id, ifp->ifindex); + ifp->name, ifp->vrf->name, + ifp->vrf->vrf_id, ifp->ifindex); } return; @@ -623,14 +623,14 @@ void if_add_update(struct interface *ifp) if (IS_ZEBRA_DEBUG_KERNEL) zlog_debug( "interface %s vrf %s(%u) index %d becomes active.", - ifp->name, VRF_LOGNAME(zvrf->vrf), ifp->vrf_id, + ifp->name, ifp->vrf->name, ifp->vrf->vrf_id, ifp->ifindex); } else { if (IS_ZEBRA_DEBUG_KERNEL) zlog_debug("interface %s vrf %s(%u) index %d is added.", - ifp->name, VRF_LOGNAME(zvrf->vrf), - ifp->vrf_id, ifp->ifindex); + ifp->name, ifp->vrf->name, ifp->vrf->vrf_id, + ifp->ifindex); } } @@ -769,12 +769,11 @@ void if_delete_update(struct interface *ifp) struct zebra_if *zif; if (if_is_up(ifp)) { - struct vrf *vrf = vrf_lookup_by_id(ifp->vrf_id); - flog_err( EC_LIB_INTERFACE, "interface %s vrf %s(%u) index %d is still up while being deleted.", - ifp->name, VRF_LOGNAME(vrf), ifp->vrf_id, ifp->ifindex); + ifp->name, ifp->vrf->name, ifp->vrf->vrf_id, + ifp->ifindex); return; } @@ -784,13 +783,10 @@ void if_delete_update(struct interface *ifp) /* Mark interface as inactive */ UNSET_FLAG(ifp->status, ZEBRA_INTERFACE_ACTIVE); - if (IS_ZEBRA_DEBUG_KERNEL) { - struct vrf *vrf = vrf_lookup_by_id(ifp->vrf_id); - + if (IS_ZEBRA_DEBUG_KERNEL) zlog_debug("interface %s vrf %s(%u) index %d is now inactive.", - ifp->name, VRF_LOGNAME(vrf), ifp->vrf_id, + ifp->name, ifp->vrf->name, ifp->vrf->vrf_id, ifp->ifindex); - } /* Delete connected routes from the kernel. */ if_delete_connected(ifp); @@ -814,7 +810,7 @@ void if_delete_update(struct interface *ifp) * occur with this implementation whereas it is not possible with * vrf-lite). */ - if (ifp->vrf_id && !vrf_is_backend_netns()) + if (ifp->vrf->vrf_id && !vrf_is_backend_netns()) if_handle_vrf_change(ifp, VRF_DEFAULT); /* Reset some zebra interface params to default values. */ @@ -842,7 +838,7 @@ void if_handle_vrf_change(struct interface *ifp, vrf_id_t vrf_id) { vrf_id_t old_vrf_id; - old_vrf_id = ifp->vrf_id; + old_vrf_id = ifp->vrf->vrf_id; /* Uninstall connected routes. */ if_uninstall_connected(ifp); @@ -884,7 +880,7 @@ void if_nbr_mac_to_ipv4ll_neigh_update(struct interface *ifp, struct in6_addr *address, int add) { - struct zebra_vrf *zvrf = vrf_info_lookup(ifp->vrf_id); + struct zebra_vrf *zvrf = ifp->vrf->info; struct zebra_if *zif = ifp->info; char buf[16] = "169.254.0.1"; struct in_addr ipv4_ll; @@ -1022,11 +1018,11 @@ void if_up(struct interface *ifp) { struct zebra_if *zif; struct interface *link_if; - struct zebra_vrf *zvrf = vrf_info_lookup(ifp->vrf_id); + struct zebra_vrf *zvrf = ifp->vrf->info; zif = ifp->info; zif->up_count++; - quagga_timestamp(2, zif->up_last, sizeof(zif->up_last)); + frr_timestamp(2, zif->up_last, sizeof(zif->up_last)); /* Notify the protocol daemons. */ if (ifp->ptm_enable && (ifp->ptm_status == ZEBRA_PTM_STATUS_DOWN)) { @@ -1086,11 +1082,11 @@ void if_down(struct interface *ifp) { struct zebra_if *zif; struct interface *link_if; - struct zebra_vrf *zvrf = vrf_info_lookup(ifp->vrf_id); + struct zebra_vrf *zvrf = ifp->vrf->info; zif = ifp->info; zif->down_count++; - quagga_timestamp(2, zif->down_last, sizeof(zif->down_last)); + frr_timestamp(2, zif->down_last, sizeof(zif->down_last)); if_down_nhg_dependents(ifp); @@ -1175,7 +1171,7 @@ void zebra_if_update_all_links(struct zebra_ns *zns) zlog_debug("bond mbr %s map to bond %d", zif->ifp->name, zif->bondslave_info.bond_ifindex); - zebra_l2_map_slave_to_bond(zif, ifp->vrf_id); + zebra_l2_map_slave_to_bond(zif, ifp->vrf->vrf_id); } /* update SVI linkages */ @@ -1205,13 +1201,115 @@ void zebra_if_set_protodown(struct interface *ifp, bool down) #endif } +/* + * Handle an interface addr event based on info in a dplane context object. + * This runs in the main pthread, using the info in the context object to + * modify an interface. + */ +void zebra_if_addr_update_ctx(struct zebra_dplane_ctx *ctx) +{ + struct interface *ifp; + uint8_t flags = 0; + const char *label = NULL; + ns_id_t ns_id; + struct zebra_ns *zns; + uint32_t metric = METRIC_MAX; + ifindex_t ifindex; + const struct prefix *addr, *dest = NULL; + enum dplane_op_e op; + + op = dplane_ctx_get_op(ctx); + ns_id = dplane_ctx_get_ns_id(ctx); + + zns = zebra_ns_lookup(ns_id); + if (zns == NULL) { + /* No ns - deleted maybe? */ + if (IS_ZEBRA_DEBUG_KERNEL) + zlog_debug("%s: can't find zns id %u", __func__, ns_id); + goto done; + } + + ifindex = dplane_ctx_get_ifindex(ctx); + + ifp = if_lookup_by_index_per_ns(zns, ifindex); + if (ifp == NULL) { + if (IS_ZEBRA_DEBUG_KERNEL) + zlog_debug("%s: can't find ifp at nsid %u index %d", + __func__, ns_id, ifindex); + goto done; + } + + addr = dplane_ctx_get_intf_addr(ctx); + + if (IS_ZEBRA_DEBUG_KERNEL) + zlog_debug("%s: %s: ifindex %u, addr %pFX", __func__, + dplane_op2str(op), ifindex, addr); + + /* Is there a peer or broadcast address? */ + dest = dplane_ctx_get_intf_dest(ctx); + if (dest->prefixlen == 0) + dest = NULL; + + if (dplane_ctx_intf_is_connected(ctx)) + SET_FLAG(flags, ZEBRA_IFA_PEER); + + /* Flags. */ + if (dplane_ctx_intf_is_secondary(ctx)) + SET_FLAG(flags, ZEBRA_IFA_SECONDARY); + + /* Label? */ + if (dplane_ctx_intf_has_label(ctx)) + label = dplane_ctx_get_intf_label(ctx); + + if (label && strcmp(ifp->name, label) == 0) + label = NULL; + + metric = dplane_ctx_get_intf_metric(ctx); + + /* Register interface address to the interface. */ + if (addr->family == AF_INET) { + if (op == DPLANE_OP_INTF_ADDR_ADD) + connected_add_ipv4( + ifp, flags, &addr->u.prefix4, addr->prefixlen, + dest ? &dest->u.prefix4 : NULL, label, metric); + else if (CHECK_FLAG(flags, ZEBRA_IFA_PEER)) { + /* Delete with a peer address */ + connected_delete_ipv4(ifp, flags, &addr->u.prefix4, + addr->prefixlen, + &dest->u.prefix4); + } else + connected_delete_ipv4(ifp, flags, &addr->u.prefix4, + addr->prefixlen, NULL); + } + + if (addr->family == AF_INET6) { + if (op == DPLANE_OP_INTF_ADDR_ADD) { + connected_add_ipv6(ifp, flags, &addr->u.prefix6, + dest ? &dest->u.prefix6 : NULL, + addr->prefixlen, label, metric); + } else + connected_delete_ipv6(ifp, &addr->u.prefix6, NULL, + addr->prefixlen); + } + + /* + * Linux kernel does not send route delete on interface down/addr del + * so we have to re-process routes it owns (i.e. kernel routes) + */ + if (op != DPLANE_OP_INTF_ADDR_ADD) + rib_update(RIB_UPDATE_KERNEL); + +done: + /* We're responsible for the ctx object */ + dplane_ctx_fini(&ctx); +} + /* Dump if address information to vty. */ static void connected_dump_vty(struct vty *vty, json_object *json, struct connected *connected) { struct prefix *p; json_object *json_addr = NULL; - char buf[PREFIX2STR_BUFFER]; /* Print interface address. */ p = connected->address; @@ -1219,8 +1317,7 @@ static void connected_dump_vty(struct vty *vty, json_object *json, if (json) { json_addr = json_object_new_object(); json_object_array_add(json, json_addr); - json_object_string_add(json_addr, "address", - prefix2str(p, buf, sizeof(buf))); + json_object_string_addf(json_addr, "address", "%pFX", p); } else { vty_out(vty, " %s %pFX", prefix_family_str(p), p); } @@ -1228,10 +1325,8 @@ static void connected_dump_vty(struct vty *vty, json_object *json, /* If there is destination address, print it. */ if (CONNECTED_PEER(connected) && connected->destination) { if (json) { - json_object_string_add( - json_addr, "peer", - prefix2str(connected->destination, buf, - sizeof(buf))); + json_object_string_addf(json_addr, "peer", "%pFX", + connected->destination); } else { vty_out(vty, " peer %pFX", connected->destination); } @@ -1278,7 +1373,8 @@ static void nbr_connected_dump_vty(struct vty *vty, json_object *json, vty_out(vty, " %s %pFX\n", prefix_family_str(p), p); } -static const char *zebra_zifslavetype_2str(zebra_slave_iftype_t zif_slave_type) +static const char * +zebra_zifslavetype_2str(enum zebra_slave_iftype zif_slave_type) { switch (zif_slave_type) { case ZEBRA_IF_SLAVE_BRIDGE: @@ -1295,7 +1391,7 @@ static const char *zebra_zifslavetype_2str(zebra_slave_iftype_t zif_slave_type) return "None"; } -static const char *zebra_ziftype_2str(zebra_iftype_t zif_type) +static const char *zebra_ziftype_2str(enum zebra_iftype zif_type) { switch (zif_type) { case ZEBRA_IF_OTHER: @@ -1512,7 +1608,6 @@ static void if_dump_vty(struct vty *vty, struct interface *ifp) struct listnode *node; struct route_node *rn; struct zebra_if *zebra_if; - struct vrf *vrf; char pd_buf[ZEBRA_PROTODOWN_RC_STR_LEN]; zebra_if = ifp->info; @@ -1540,8 +1635,7 @@ static void if_dump_vty(struct vty *vty, struct interface *ifp) zebra_ptm_show_status(vty, NULL, ifp); - vrf = vrf_lookup_by_id(ifp->vrf_id); - vty_out(vty, " vrf: %s\n", vrf->name); + vty_out(vty, " vrf: %s\n", ifp->vrf->name); if (ifp->desc) vty_out(vty, " Description: %s\n", ifp->desc); @@ -1837,7 +1931,6 @@ static void if_dump_vty_json(struct vty *vty, struct interface *ifp, struct listnode *node; struct route_node *rn; struct zebra_if *zebra_if; - struct vrf *vrf; char pd_buf[ZEBRA_PROTODOWN_RC_STR_LEN]; char buf[BUFSIZ]; json_object *json_if; @@ -1875,8 +1968,7 @@ static void if_dump_vty_json(struct vty *vty, struct interface *ifp, zebra_ptm_show_status(vty, json, ifp); - vrf = vrf_lookup_by_id(ifp->vrf_id); - json_object_string_add(json_if, "vrfName", vrf->name); + json_object_string_add(json_if, "vrfName", ifp->vrf->name); if (ifp->desc) json_object_string_add(json_if, "description", ifp->desc); @@ -1962,18 +2054,14 @@ static void if_dump_vty_json(struct vty *vty, struct interface *ifp, vxlan_info = &zebra_if->l2info.vxl; json_object_int_add(json_if, "vxlanId", vxlan_info->vni); if (vxlan_info->vtep_ip.s_addr != INADDR_ANY) - json_object_string_add(json_if, "vtepIp", - inet_ntop(AF_INET, - &vxlan_info->vtep_ip, - buf, sizeof(buf))); + json_object_string_addf(json_if, "vtepIp", "%pI4", + &vxlan_info->vtep_ip); if (vxlan_info->access_vlan) json_object_int_add(json_if, "accessVlanId", vxlan_info->access_vlan); if (vxlan_info->mcast_grp.s_addr != INADDR_ANY) - json_object_string_add(json_if, "mcastGroup", - inet_ntop(AF_INET, - &vxlan_info->mcast_grp, - buf, sizeof(buf))); + json_object_string_addf(json_if, "mcastGroup", "%pI4", + &vxlan_info->mcast_grp); if (vxlan_info->ifindex_link && (vxlan_info->link_nsid != NS_UNKNOWN)) { struct interface *ifp; @@ -1990,16 +2078,12 @@ static void if_dump_vty_json(struct vty *vty, struct interface *ifp, gre_info = &zebra_if->l2info.gre; if (gre_info->vtep_ip.s_addr != INADDR_ANY) { - json_object_string_add(json_if, "vtepIp", - inet_ntop(AF_INET, - &gre_info->vtep_ip, - buf, sizeof(buf))); + json_object_string_addf(json_if, "vtepIp", "%pI4", + &gre_info->vtep_ip); if (gre_info->vtep_ip_remote.s_addr != INADDR_ANY) - json_object_string_add( - json_if, "vtepRemoteIp", - inet_ntop(AF_INET, - &gre_info->vtep_ip_remote, - buf, sizeof(buf))); + json_object_string_addf( + json_if, "vtepRemoteIp", "%pI4", + &gre_info->vtep_ip_remote); } if (gre_info->ifindex_link && (gre_info->link_nsid != NS_UNKNOWN)) { @@ -2133,9 +2217,8 @@ static void if_dump_vty_json(struct vty *vty, struct interface *ifp, json_object_double_add(json_te, "utilizedBandwidth", iflp->use_bw); if (IS_PARAM_SET(iflp, LP_RMT_AS)) - json_object_string_add(json_te, "neighborAsbrIp", - inet_ntop(AF_INET, &iflp->rmt_ip, - buf, sizeof(buf))); + json_object_string_addf(json_te, "neighborAsbrIp", + "%pI4", &iflp->rmt_ip); json_object_int_add(json_te, "neighborAsbrAs", iflp->rmt_as); } @@ -2261,12 +2344,8 @@ DEFPY(show_interface, show_interface_cmd, } } - if (json) { - vty_out(vty, "%s\n", - json_object_to_json_string_ext( - json, JSON_C_TO_STRING_PRETTY)); - json_object_free(json); - } + if (json) + vty_json(vty, json); return CMD_SUCCESS; } @@ -2308,12 +2387,8 @@ DEFPY (show_interface_vrf_all, } } - if (json) { - vty_out(vty, "%s\n", - json_object_to_json_string_ext( - json, JSON_C_TO_STRING_PRETTY)); - json_object_free(json); - } + if (json) + vty_json(vty, json); return CMD_SUCCESS; } @@ -2361,12 +2436,8 @@ DEFPY (show_interface_name_vrf, else if_dump_vty(vty, ifp); - if (json) { - vty_out(vty, "%s\n", - json_object_to_json_string_ext( - json, JSON_C_TO_STRING_PRETTY)); - json_object_free(json); - } + if (json) + vty_json(vty, json); return CMD_SUCCESS; } @@ -2381,12 +2452,24 @@ DEFPY (show_interface_name_vrf_all, VRF_ALL_CMD_HELP_STR JSON_STR) { - struct interface *ifp; + struct interface *ifp = NULL; + struct interface *ifptmp; + struct vrf *vrf; json_object *json = NULL; + int count = 0; interface_update_stats(); - ifp = if_lookup_by_name_all_vrf(ifname); + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { + ifptmp = if_lookup_by_name_vrf(ifname, vrf); + if (ifptmp) { + ifp = ifptmp; + count++; + if (!vrf_is_backend_netns()) + break; + } + } + if (ifp == NULL) { if (uj) vty_out(vty, "{}\n"); @@ -2394,6 +2477,17 @@ DEFPY (show_interface_name_vrf_all, vty_out(vty, "%% Can't find interface %s\n", ifname); return CMD_WARNING; } + if (count > 1) { + if (uj) { + vty_out(vty, "{}\n"); + } else { + vty_out(vty, + "%% There are multiple interfaces with name %s\n", + ifname); + vty_out(vty, "%% You must specify the VRF name\n"); + } + return CMD_WARNING; + } if (uj) json = json_object_new_object(); @@ -2403,12 +2497,8 @@ DEFPY (show_interface_name_vrf_all, else if_dump_vty(vty, ifp); - if (json) { - vty_out(vty, "%s\n", - json_object_to_json_string_ext( - json, JSON_C_TO_STRING_PRETTY)); - json_object_free(json); - } + if (json) + vty_json(vty, json); return CMD_SUCCESS; } @@ -2782,6 +2872,7 @@ struct cmd_node link_params_node = { .node = LINK_PARAMS_NODE, .parent_node = INTERFACE_NODE, .prompt = "%s(config-link-params)# ", + .no_xpath = true, }; static void link_param_cmd_set_uint32(struct interface *ifp, uint32_t *field, @@ -4096,29 +4187,27 @@ static int link_params_config_write(struct vty *vty, struct interface *ifp) if (IS_PARAM_SET(iflp, LP_RMT_AS)) vty_out(vty, " neighbor %pI4 as %u\n", &iflp->rmt_ip, iflp->rmt_as); - vty_out(vty, " exit-link-params\n"); + vty_out(vty, " exit-link-params\n"); return 0; } static int if_config_write(struct vty *vty) { - struct vrf *vrf0; + struct vrf *vrf; struct interface *ifp; zebra_ptm_write(vty); - RB_FOREACH (vrf0, vrf_name_head, &vrfs_by_name) - FOR_ALL_INTERFACES (vrf0, ifp) { + RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) + FOR_ALL_INTERFACES (vrf, ifp) { struct zebra_if *if_data; struct listnode *addrnode; struct connected *ifc; struct prefix *p; - struct vrf *vrf; if_data = ifp->info; - vrf = vrf_lookup_by_id(ifp->vrf_id); - if (ifp->vrf_id == VRF_DEFAULT) + if (ifp->vrf->vrf_id == VRF_DEFAULT) vty_frame(vty, "interface %s\n", ifp->name); else vty_frame(vty, "interface %s vrf %s\n", @@ -4188,7 +4277,7 @@ static int if_config_write(struct vty *vty) zebra_evpn_mh_if_write(vty, ifp); link_params_config_write(vty, ifp); - vty_endframe(vty, "!\n"); + vty_endframe(vty, "exit\n!\n"); } return 0; } |
