diff options
Diffstat (limited to 'zebra/rt_netlink.c')
| -rw-r--r-- | zebra/rt_netlink.c | 114 |
1 files changed, 46 insertions, 68 deletions
diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index 46a751ce69..55e0775a8c 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -41,7 +41,6 @@ #include "connected.h" #include "table.h" #include "memory.h" -#include "zebra_memory.h" #include "rib.h" #include "thread.h" #include "privs.h" @@ -1767,6 +1766,33 @@ ssize_t netlink_route_multipath_msg_encode(int cmd, nl_attr_nest_end(&req->n, nest); } + /* + * Always install blackhole routes without using nexthops, because of + * the following kernel problems: + * 1. Kernel nexthops don't suport unreachable/prohibit route types. + * 2. Blackhole kernel nexthops are deleted when loopback is down. + */ + nexthop = dplane_ctx_get_ng(ctx)->nexthop; + if (nexthop) { + if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) + nexthop = nexthop->resolved; + + if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE) { + switch (nexthop->bh_type) { + case BLACKHOLE_ADMINPROHIB: + req->r.rtm_type = RTN_PROHIBIT; + break; + case BLACKHOLE_REJECT: + req->r.rtm_type = RTN_UNREACHABLE; + break; + default: + req->r.rtm_type = RTN_BLACKHOLE; + break; + } + return NLMSG_ALIGN(req->n.nlmsg_len); + } + } + if ((!fpm && kernel_nexthops_supported() && (!proto_nexthops_only() || is_proto_nhg(dplane_ctx_get_nhe_id(ctx), 0))) @@ -1820,27 +1846,6 @@ ssize_t netlink_route_multipath_msg_encode(int cmd, if (nexthop_num == 1) { nexthop_num = 0; for (ALL_NEXTHOPS_PTR(dplane_ctx_get_ng(ctx), nexthop)) { - /* - * So we want to cover 2 types of blackhole - * routes here: - * 1) A normal blackhole route( ala from a static - * install. - * 2) A recursively resolved blackhole route - */ - if (nexthop->type == NEXTHOP_TYPE_BLACKHOLE) { - switch (nexthop->bh_type) { - case BLACKHOLE_ADMINPROHIB: - req->r.rtm_type = RTN_PROHIBIT; - break; - case BLACKHOLE_REJECT: - req->r.rtm_type = RTN_UNREACHABLE; - break; - default: - req->r.rtm_type = RTN_BLACKHOLE; - break; - } - return NLMSG_ALIGN(req->n.nlmsg_len); - } if (CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_RECURSIVE)) { @@ -2833,7 +2838,6 @@ static int netlink_macfdb_change(struct nlmsghdr *h, int len, ns_id_t ns_id) vlanid_t vid = 0; struct in_addr vtep_ip; int vid_present = 0, dst_present = 0; - char buf[ETHER_ADDR_STRLEN]; char vid_buf[20]; char dst_buf[30]; bool sticky; @@ -2912,11 +2916,10 @@ static int netlink_macfdb_change(struct nlmsghdr *h, int len, ns_id_t ns_id) } if (IS_ZEBRA_DEBUG_KERNEL) - zlog_debug("Rx %s AF_BRIDGE IF %u%s st 0x%x fl 0x%x MAC %s%s nhg %d", + zlog_debug("Rx %s AF_BRIDGE IF %u%s st 0x%x fl 0x%x MAC %pEA%s nhg %d", nl_msg_type_to_str(h->nlmsg_type), ndm->ndm_ifindex, vid_present ? vid_buf : "", - ndm->ndm_state, ndm->ndm_flags, - prefix_mac2str(&mac, buf, sizeof(buf)), + ndm->ndm_state, ndm->ndm_flags, &mac, dst_present ? dst_buf : "", nhg_id); /* The interface should exist. */ @@ -3117,7 +3120,6 @@ static int netlink_request_specific_mac_in_bridge(struct zebra_ns *zns, char buf[256]; } req; struct zebra_if *br_zif; - char buf[ETHER_ADDR_STRLEN]; memset(&req, 0, sizeof(req)); req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ndmsg)); @@ -3136,11 +3138,10 @@ static int netlink_request_specific_mac_in_bridge(struct zebra_ns *zns, if (IS_ZEBRA_DEBUG_KERNEL) zlog_debug( - "%s: Tx family %s IF %s(%u) vrf %s(%u) MAC %s vid %u", + "%s: Tx family %s IF %s(%u) vrf %s(%u) MAC %pEA vid %u", __func__, nl_family_to_str(req.ndm.ndm_family), br_if->name, br_if->ifindex, - vrf_id_to_name(br_if->vrf_id), br_if->vrf_id, - prefix_mac2str(mac, buf, sizeof(buf)), vid); + vrf_id_to_name(br_if->vrf_id), br_if->vrf_id, mac, vid); return netlink_request(&zns->netlink_cmd, &req); } @@ -3225,8 +3226,6 @@ ssize_t netlink_macfdb_update_ctx(struct zebra_dplane_ctx *ctx, void *data, SET_IPADDR_V4(&vtep_ip); if (IS_ZEBRA_DEBUG_KERNEL) { - char ipbuf[PREFIX_STRLEN]; - char buf[ETHER_ADDR_STRLEN]; char vid_buf[20]; const struct ethaddr *mac = dplane_ctx_mac_get_addr(ctx); @@ -3237,12 +3236,11 @@ ssize_t netlink_macfdb_update_ctx(struct zebra_dplane_ctx *ctx, void *data, vid_buf[0] = '\0'; zlog_debug( - "Tx %s family %s IF %s(%u)%s %sMAC %s dst %s nhg %u%s%s%s%s%s", + "Tx %s family %s IF %s(%u)%s %sMAC %pEA dst %pIA nhg %u%s%s%s%s%s", nl_msg_type_to_str(cmd), nl_family_to_str(AF_BRIDGE), dplane_ctx_get_ifname(ctx), dplane_ctx_get_ifindex(ctx), vid_buf, dplane_ctx_mac_is_sticky(ctx) ? "sticky " : "", - prefix_mac2str(mac, buf, sizeof(buf)), - ipaddr2str(&vtep_ip, ipbuf, sizeof(ipbuf)), nhg_id, + mac, &vtep_ip, nhg_id, (update_flags & DPLANE_MAC_REMOTE) ? " rem" : "", (update_flags & DPLANE_MAC_WAS_STATIC) ? " clr_sync" : "", @@ -3303,7 +3301,6 @@ static int netlink_ipneigh_change(struct nlmsghdr *h, int len, ns_id_t ns_id) struct ipaddr ip; struct vrf *vrf; char buf[ETHER_ADDR_STRLEN]; - char buf2[INET6_ADDRSTRLEN]; int mac_present = 0; bool is_ext; bool is_router; @@ -3409,11 +3406,11 @@ static int netlink_ipneigh_change(struct nlmsghdr *h, int len, ns_id_t ns_id) if (IS_ZEBRA_DEBUG_KERNEL) zlog_debug( - "Rx %s family %s IF %s(%u) vrf %s(%u) IP %s MAC %s state 0x%x flags 0x%x ext_flags 0x%x", + "Rx %s family %s IF %s(%u) vrf %s(%u) IP %pIA MAC %s state 0x%x flags 0x%x ext_flags 0x%x", nl_msg_type_to_str(h->nlmsg_type), nl_family_to_str(ndm->ndm_family), ifp->name, ndm->ndm_ifindex, VRF_LOGNAME(vrf), ifp->vrf_id, - ipaddr2str(&ip, buf2, sizeof(buf2)), + &ip, mac_present ? prefix_mac2str(&mac, buf, sizeof(buf)) : "", @@ -3445,11 +3442,11 @@ static int netlink_ipneigh_change(struct nlmsghdr *h, int len, ns_id_t ns_id) } if (IS_ZEBRA_DEBUG_KERNEL) - zlog_debug("Rx %s family %s IF %s(%u) vrf %s(%u) IP %s", + zlog_debug("Rx %s family %s IF %s(%u) vrf %s(%u) IP %pIA", nl_msg_type_to_str(h->nlmsg_type), nl_family_to_str(ndm->ndm_family), ifp->name, ndm->ndm_ifindex, VRF_LOGNAME(vrf), ifp->vrf_id, - ipaddr2str(&ip, buf2, sizeof(buf2))); + &ip); /* Process the delete - it may result in re-adding the neighbor if it is * a valid "remote" neighbor. @@ -3576,14 +3573,11 @@ static int netlink_request_specific_neigh_in_vlan(struct zebra_ns *zns, nl_attr_put(&req.n, sizeof(req), NDA_DST, &ip->ip.addr, ipa_len); - if (IS_ZEBRA_DEBUG_KERNEL) { - char buf[INET6_ADDRSTRLEN]; - - zlog_debug("%s: Tx %s family %s IF %u IP %s flags 0x%x", + if (IS_ZEBRA_DEBUG_KERNEL) + zlog_debug("%s: Tx %s family %s IF %u IP %pIA flags 0x%x", __func__, nl_msg_type_to_str(type), - nl_family_to_str(req.ndm.ndm_family), ifindex, - ipaddr2str(ip, buf, sizeof(buf)), req.n.nlmsg_flags); - } + nl_family_to_str(req.ndm.ndm_family), ifindex, ip, + req.n.nlmsg_flags); return netlink_request(&zns->netlink_cmd, &req); } @@ -3594,7 +3588,6 @@ int netlink_neigh_read_specific_ip(struct ipaddr *ip, int ret = 0; struct zebra_ns *zns; struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(vlan_if->vrf_id); - char buf[INET6_ADDRSTRLEN]; struct zebra_dplane_info dp_info; zns = zvrf->zns; @@ -3602,9 +3595,8 @@ int netlink_neigh_read_specific_ip(struct ipaddr *ip, zebra_dplane_info_from_zns(&dp_info, zns, true /*is_cmd*/); if (IS_ZEBRA_DEBUG_KERNEL) - zlog_debug("%s: neigh request IF %s(%u) IP %s vrf %s(%u)", - __func__, vlan_if->name, vlan_if->ifindex, - ipaddr2str(ip, buf, sizeof(buf)), + zlog_debug("%s: neigh request IF %s(%u) IP %pIA vrf %s(%u)", + __func__, vlan_if->name, vlan_if->ifindex, ip, vrf_id_to_name(vlan_if->vrf_id), vlan_if->vrf_id); ret = netlink_request_specific_neigh_in_vlan(zns, RTM_GETNEIGH, ip, @@ -3695,27 +3687,13 @@ static ssize_t netlink_neigh_update_ctx(const struct zebra_dplane_ctx *ctx, /* local neigh */ if (update_flags & DPLANE_NEIGH_SET_STATIC) ext_flags |= NTF_E_MH_PEER_SYNC; - - /* the ndm_state set for local entries can be REACHABLE or - * STALE. if the dataplane has already establish reachability - * (in the meantime) FRR must not over-write it with STALE. - * this accidental race/over-write is avoided by using the - * WEAK_OVERRIDE_STATE - */ - ext_flags |= NTF_E_WEAK_OVERRIDE_STATE; } - if (IS_ZEBRA_DEBUG_KERNEL) { - char buf[INET6_ADDRSTRLEN]; - char buf2[ETHER_ADDR_STRLEN]; - + if (IS_ZEBRA_DEBUG_KERNEL) zlog_debug( - "Tx %s family %s IF %s(%u) Neigh %s MAC %s flags 0x%x state 0x%x %sext_flags 0x%x", + "Tx %s family %s IF %s(%u) Neigh %pIA MAC %pEA flags 0x%x state 0x%x %sext_flags 0x%x", nl_msg_type_to_str(cmd), nl_family_to_str(family), dplane_ctx_get_ifname(ctx), dplane_ctx_get_ifindex(ctx), - ipaddr2str(ip, buf, sizeof(buf)), - mac ? prefix_mac2str(mac, buf2, sizeof(buf2)) : "null", - flags, state, ext ? "ext " : "", ext_flags); - } + ip, mac, flags, state, ext ? "ext " : "", ext_flags); return netlink_neigh_update_msg_encode( ctx, cmd, mac, ip, true, family, RTN_UNICAST, flags, state, |
