diff --git a/bfdd/bfd.c b/bfdd/bfd.c index 9667ba8708..ca4bf94955 100644 --- a/bfdd/bfd.c +++ b/bfdd/bfd.c @@ -313,6 +313,13 @@ int bfd_session_enable(struct bfd_session *bs) } } + if (!vrf_is_backend_netns() && vrf && vrf->vrf_id != VRF_DEFAULT + && !if_lookup_by_name(vrf->name, vrf->vrf_id)) { + zlog_err("session-enable: vrf interface %s not available yet", + vrf->name); + return 0; + } + if (bs->key.ifname[0]) { if (vrf) ifp = if_lookup_by_name(bs->key.ifname, vrf->vrf_id); @@ -320,14 +327,16 @@ int bfd_session_enable(struct bfd_session *bs) ifp = if_lookup_by_name_all_vrf(bs->key.ifname); if (ifp == NULL) { zlog_err( - "session-enable: specified interface doesn't exists."); + "session-enable: specified interface %s (VRF %s) doesn't exist.", + bs->key.ifname, vrf ? vrf->name : ""); return 0; } if (bs->key.ifname[0] && !vrf) { vrf = vrf_lookup_by_id(ifp->vrf_id); if (vrf == NULL) { zlog_err( - "session-enable: specified VRF doesn't exists."); + "session-enable: specified VRF %u doesn't exist.", + ifp->vrf_id); return 0; } } diff --git a/bfdd/bfd_packet.c b/bfdd/bfd_packet.c index 0a71c18a42..076318e6ca 100644 --- a/bfdd/bfd_packet.c +++ b/bfdd/bfd_packet.c @@ -543,6 +543,7 @@ int bfd_recv_cb(struct thread *t) ifindex_t ifindex = IFINDEX_INTERNAL; struct sockaddr_any local, peer; uint8_t msgbuf[1516]; + struct interface *ifp = NULL; struct bfd_vrf_global *bvrf = THREAD_ARG(t); vrfid = bvrf->vrf->vrf_id; @@ -572,6 +573,15 @@ int bfd_recv_cb(struct thread *t) &local, &peer); } + /* update vrf-id because when in vrf-lite mode, + * the socket is on default namespace + */ + if (ifindex) { + ifp = if_lookup_by_index(ifindex, vrfid); + if (ifp) + vrfid = ifp->vrf_id; + } + /* Implement RFC 5880 6.8.6 */ if (mlen < BFD_PKT_LEN) { cp_debug(is_mhop, &peer, &local, ifindex, vrfid, @@ -951,8 +961,9 @@ int bp_peer_socket(const struct bfd_session *bs) if (bs->key.ifname[0]) device_to_bind = (const char *)bs->key.ifname; - else if (CHECK_FLAG(bs->flags, BFD_SESS_FLAG_MH) - && bs->key.vrfname[0]) + else if ((!vrf_is_backend_netns() && bs->vrf->vrf_id != VRF_DEFAULT) + || ((CHECK_FLAG(bs->flags, BFD_SESS_FLAG_MH) + && bs->key.vrfname[0]))) device_to_bind = (const char *)bs->key.vrfname; frr_with_privs(&bglobal.bfdd_privs) { @@ -1018,8 +1029,9 @@ int bp_peer_socketv6(const struct bfd_session *bs) if (bs->key.ifname[0]) device_to_bind = (const char *)bs->key.ifname; - else if (CHECK_FLAG(bs->flags, BFD_SESS_FLAG_MH) - && bs->key.vrfname[0]) + else if ((!vrf_is_backend_netns() && bs->vrf->vrf_id != VRF_DEFAULT) + || ((CHECK_FLAG(bs->flags, BFD_SESS_FLAG_MH) + && bs->key.vrfname[0]))) device_to_bind = (const char *)bs->key.vrfname; frr_with_privs(&bglobal.bfdd_privs) { diff --git a/bfdd/ptm_adapter.c b/bfdd/ptm_adapter.c index 44519c47b5..57fb81aa27 100644 --- a/bfdd/ptm_adapter.c +++ b/bfdd/ptm_adapter.c @@ -669,17 +669,24 @@ static void bfdd_sessions_enable_interface(struct interface *ifp) struct bfd_session *bs; struct vrf *vrf; + vrf = vrf_lookup_by_id(ifp->vrf_id); + if (!vrf) + return; + TAILQ_FOREACH(bso, &bglobal.bg_obslist, bso_entry) { bs = bso->bso_bs; - /* Interface name mismatch. */ - if (strcmp(ifp->name, bs->key.ifname)) - continue; - vrf = vrf_lookup_by_id(ifp->vrf_id); - if (!vrf) - continue; + /* check vrf name */ if (bs->key.vrfname[0] && strcmp(vrf->name, bs->key.vrfname)) continue; + + /* If Interface matches vrfname, then bypass iface check */ + if (vrf_is_backend_netns() || strcmp(ifp->name, vrf->name)) { + /* Interface name mismatch. */ + if (strcmp(ifp->name, bs->key.ifname)) + continue; + } + /* Skip enabled sessions. */ if (bs->sock != -1) continue; @@ -759,7 +766,8 @@ void bfdd_sessions_disable_vrf(struct vrf *vrf) static int bfd_ifp_destroy(struct interface *ifp) { if (bglobal.debug_zebra) - zlog_debug("zclient: delete interface %s", ifp->name); + zlog_debug("zclient: delete interface %s (VRF %u)", ifp->name, + ifp->vrf_id); bfdd_sessions_disable_interface(ifp); @@ -812,10 +820,10 @@ static int bfdd_interface_address_update(ZAPI_CALLBACK_ARGS) return 0; if (bglobal.debug_zebra) - zlog_debug("zclient: %s local address %pFX", + zlog_debug("zclient: %s local address %pFX (VRF %u)", cmd == ZEBRA_INTERFACE_ADDRESS_ADD ? "add" : "delete", - ifc->address); + ifc->address, vrf_id); if (cmd == ZEBRA_INTERFACE_ADDRESS_ADD) bfdd_sessions_enable_address(ifc); @@ -828,8 +836,8 @@ static int bfdd_interface_address_update(ZAPI_CALLBACK_ARGS) static int bfd_ifp_create(struct interface *ifp) { if (bglobal.debug_zebra) - zlog_debug("zclient: add interface %s", ifp->name); - + zlog_debug("zclient: add interface %s (VRF %u)", ifp->name, + ifp->vrf_id); bfdd_sessions_enable_interface(ifp); return 0;