diff options
author | Donald Sharp <sharpd@cumulusnetworks.com> | 2018-01-30 19:30:36 +0100 |
---|---|---|
committer | Donald Sharp <sharpd@cumulusnetworks.com> | 2018-02-09 02:31:36 +0100 |
commit | c83c5e4482580351d20fb45dc643c368866e33d8 (patch) | |
tree | 994650b9c5f16ba268ab936c1395cc724aefef99 /zebra/zserv.c | |
parent | lib, zebra: Move nh_resolve_via_default to appropriate header (diff) | |
download | frr-c83c5e4482580351d20fb45dc643c368866e33d8.tar.xz frr-c83c5e4482580351d20fb45dc643c368866e33d8.zip |
lib, zebra: Add new api to specify a label associated with the vrf
For L3VPN's we need to create a label associated with the specified
vrf to be installed into the kernel to allow a pop and lookup
operation.
The new api is:
zclient_send_vrf_label(struct zclient *zclient, vrf_id_t vrf_id,
mpls_label_t label);
For the specified vrf_id associate the specified label for
a pop and lookup operation for forwarding.
To setup a POP and Forward use MPLS_LABEL_IMPLICIT_NULL
If the same label is passed in we ignore the call.
If the label is different we update entry.
If the label is MPLS_LABEL_NONE we remove
the entry.
This sets up the api. Future commits will have the functionality
to actually install into the kernel.
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
Diffstat (limited to '')
-rw-r--r-- | zebra/zserv.c | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/zebra/zserv.c b/zebra/zserv.c index 9da8d593e..5f2757f52 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -2486,6 +2486,51 @@ stream_failure: return 1; } +static void zread_vrf_label(struct zserv *client, + struct zebra_vrf *zvrf) +{ + struct interface *ifp; + mpls_label_t nlabel; + struct stream *s; + struct zebra_vrf *def_zvrf; + + s = client->ibuf; + STREAM_GETL(s, nlabel); + + if (nlabel == zvrf->label) { + /* + * Nothing to do here move along + */ + return; + } + + if (zvrf->vrf->vrf_id != VRF_DEFAULT) + ifp = if_lookup_by_name(zvrf->vrf->name, zvrf->vrf->vrf_id); + else + ifp = if_lookup_by_name("lo", VRF_DEFAULT); + + if (!ifp) { + zlog_debug("Unable to find specified Interface for %s", + zvrf->vrf->name); + return; + } + + def_zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT); + + if (zvrf->label != MPLS_LABEL_IPV4NULL) + mpls_lsp_uninstall(def_zvrf, ZEBRA_LSP_STATIC, + zvrf->label, NEXTHOP_TYPE_IFINDEX, + NULL, ifp->ifindex); + + if (nlabel != MPLS_LABEL_IPV4NULL) + mpls_lsp_install(def_zvrf, ZEBRA_LSP_STATIC, nlabel, + MPLS_LABEL_IMPLICIT_NULL, NEXTHOP_TYPE_IFINDEX, NULL, ifp->ifindex); + + zvrf->label = nlabel; +stream_failure: + return; +} + static inline void zserv_handle_commands(struct zserv *client, uint16_t command, uint16_t length, @@ -2570,6 +2615,9 @@ static inline void zserv_handle_commands(struct zserv *client, case ZEBRA_VRF_UNREGISTER: zread_vrf_unregister(client, length, zvrf); break; + case ZEBRA_VRF_LABEL: + zread_vrf_label(client, zvrf); + break; case ZEBRA_BFD_CLIENT_REGISTER: zebra_ptm_bfd_client_register(client, length); break; |