mirror of
https://git.proxmox.com/git/mirror_frr
synced 2026-01-27 05:30:42 +00:00
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>
This commit is contained in:
parent
44bdf1590d
commit
c83c5e4482
@ -929,6 +929,7 @@ static const struct zebra_desc_table command_types[] = {
|
||||
DESC_ENTRY(ZEBRA_VRF_UNREGISTER),
|
||||
DESC_ENTRY(ZEBRA_VRF_ADD),
|
||||
DESC_ENTRY(ZEBRA_VRF_DELETE),
|
||||
DESC_ENTRY(ZEBRA_VRF_LABEL),
|
||||
DESC_ENTRY(ZEBRA_INTERFACE_VRF_UPDATE),
|
||||
DESC_ENTRY(ZEBRA_BFD_CLIENT_REGISTER),
|
||||
DESC_ENTRY(ZEBRA_INTERFACE_ENABLE_RADV),
|
||||
|
||||
@ -363,6 +363,20 @@ static int zebra_hello_send(struct zclient *zclient)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void zclient_send_vrf_label(struct zclient *zclient, vrf_id_t vrf_id,
|
||||
mpls_label_t label)
|
||||
{
|
||||
struct stream *s;
|
||||
|
||||
s = zclient->obuf;
|
||||
stream_reset(s);
|
||||
|
||||
zclient_create_header(s, ZEBRA_VRF_LABEL, vrf_id);
|
||||
stream_putl(s, label);
|
||||
stream_putw_at(s, 0, stream_get_endp(s));
|
||||
zclient_send_message(zclient);
|
||||
}
|
||||
|
||||
/* Send register requests to zebra daemon for the information in a VRF. */
|
||||
void zclient_send_reg_requests(struct zclient *zclient, vrf_id_t vrf_id)
|
||||
{
|
||||
|
||||
@ -93,6 +93,7 @@ typedef enum {
|
||||
ZEBRA_VRF_UNREGISTER,
|
||||
ZEBRA_VRF_ADD,
|
||||
ZEBRA_VRF_DELETE,
|
||||
ZEBRA_VRF_LABEL,
|
||||
ZEBRA_INTERFACE_VRF_UPDATE,
|
||||
ZEBRA_BFD_CLIENT_REGISTER,
|
||||
ZEBRA_INTERFACE_ENABLE_RADV,
|
||||
@ -382,6 +383,17 @@ extern u_short *redist_check_instance(struct redist_proto *, u_short);
|
||||
extern void redist_add_instance(struct redist_proto *, u_short);
|
||||
extern void redist_del_instance(struct redist_proto *, u_short);
|
||||
|
||||
/*
|
||||
* Send to zebra that the specified vrf is using label to resolve
|
||||
* itself for L3VPN's. Repeated calls of this function with
|
||||
* different labels will cause an effective update of the
|
||||
* label for lookup. If you pass in MPLS_V4_EXP_NULL_LABEL
|
||||
* we will cause a delete action and remove this label pop
|
||||
* operation.
|
||||
*/
|
||||
extern void zclient_send_vrf_label(struct zclient *zclient, vrf_id_t vrf_id,
|
||||
mpls_label_t label);
|
||||
|
||||
extern void zclient_send_reg_requests(struct zclient *, vrf_id_t);
|
||||
extern void zclient_send_dereg_requests(struct zclient *, vrf_id_t);
|
||||
|
||||
|
||||
@ -79,6 +79,9 @@ struct zebra_vrf {
|
||||
*/
|
||||
struct zebra_ns *zns;
|
||||
|
||||
/* MPLS Label to handle L3VPN <-> vrf popping */
|
||||
mpls_label_t label;
|
||||
|
||||
/* MPLS static LSP config table */
|
||||
struct hash *slsp_table;
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user