From 7d061b3cb120c35c5b580bbbcfb1ec9602f58956 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Wed, 14 Feb 2018 01:11:09 -0500 Subject: [PATCH 1/2] lib, sharpd, zebra: Update the zapi_vrf_label call to add afi Add the ability to pass in an afi to zebra. zebra_vrf keeps track of the afi/label tuple and then does the right thing before we call down. AF_MPLS does not care about v4 or v6 it just knows label and what device to use for lookup. Signed-off-by: Donald Sharp --- lib/zclient.c | 3 ++- lib/zclient.h | 8 +++++++- sharpd/sharp_vty.c | 7 +++++-- sharpd/sharp_zebra.c | 4 ++-- sharpd/sharp_zebra.h | 2 +- zebra/zebra_vrf.h | 2 +- zebra/zserv.c | 12 ++++++++---- 7 files changed, 26 insertions(+), 12 deletions(-) diff --git a/lib/zclient.c b/lib/zclient.c index 8e8b50b15e..714888a3f3 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -363,7 +363,7 @@ static int zebra_hello_send(struct zclient *zclient) return 0; } -void zclient_send_vrf_label(struct zclient *zclient, vrf_id_t vrf_id, +void zclient_send_vrf_label(struct zclient *zclient, vrf_id_t vrf_id, afi_t afi, mpls_label_t label, enum lsp_types_t ltype) { struct stream *s; @@ -373,6 +373,7 @@ void zclient_send_vrf_label(struct zclient *zclient, vrf_id_t vrf_id, zclient_create_header(s, ZEBRA_VRF_LABEL, vrf_id); stream_putl(s, label); + stream_putc(s, afi); stream_putc(s, ltype); stream_putw_at(s, 0, stream_get_endp(s)); zclient_send_message(zclient); diff --git a/lib/zclient.h b/lib/zclient.h index 344b45fb54..d8a70c6cf3 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -390,9 +390,15 @@ extern void redist_del_instance(struct redist_proto *, u_short); * label for lookup. If you pass in MPLS_LABEL_NONE * we will cause a delete action and remove this label pop * operation. + * + * The underlying AF_MPLS doesn't care about afi's + * but we can make the zebra_vrf keep track of what + * we have installed and play some special games + * to get them both installed. */ extern void zclient_send_vrf_label(struct zclient *zclient, vrf_id_t vrf_id, - mpls_label_t label, enum lsp_types_t ltype); + afi_t afi, mpls_label_t label, + enum lsp_types_t ltype); extern void zclient_send_reg_requests(struct zclient *, vrf_id_t); extern void zclient_send_dereg_requests(struct zclient *, vrf_id_t); diff --git a/sharpd/sharp_vty.c b/sharpd/sharp_vty.c index 4f7d61b22f..0e7d1f2c29 100644 --- a/sharpd/sharp_vty.c +++ b/sharpd/sharp_vty.c @@ -80,14 +80,17 @@ DEFPY (install_routes, } DEFPY(vrf_label, vrf_label_cmd, - "sharp label vrf NAME$name label (0-100000)$label", + "sharp label vrf NAME$name label (0-100000)$label", "Sharp Routing Protocol\n" "Give a vrf a label\n" + "Pop and forward for IPv4\n" + "Pop and forward for IPv6\n" VRF_CMD_HELP_STR "The label to use, 0 specifies remove the label installed from previous\n" "Specified range to use\n") { struct vrf *vrf; + afi_t afi = (ipv4) ? AFI_IP : AFI_IP6; if (strcmp(name, "default") == 0) vrf = vrf_lookup_by_id(VRF_DEFAULT); @@ -102,7 +105,7 @@ DEFPY(vrf_label, vrf_label_cmd, if (label == 0) label = MPLS_LABEL_NONE; - vrf_label_add(vrf->vrf_id, label); + vrf_label_add(vrf->vrf_id, afi, label); return CMD_SUCCESS; } diff --git a/sharpd/sharp_zebra.c b/sharpd/sharp_zebra.c index f771e53f0c..78e8cf0adc 100644 --- a/sharpd/sharp_zebra.c +++ b/sharpd/sharp_zebra.c @@ -152,9 +152,9 @@ static void zebra_connected(struct zclient *zclient) zclient_send_reg_requests(zclient, VRF_DEFAULT); } -void vrf_label_add(vrf_id_t vrf_id, mpls_label_t label) +void vrf_label_add(vrf_id_t vrf_id, afi_t afi, mpls_label_t label) { - zclient_send_vrf_label(zclient, vrf_id, label, ZEBRA_LSP_SHARP); + zclient_send_vrf_label(zclient, vrf_id, afi, label, ZEBRA_LSP_SHARP); } void route_add(struct prefix *p, struct nexthop *nh) diff --git a/sharpd/sharp_zebra.h b/sharpd/sharp_zebra.h index 281c67ff94..0bba443bd4 100644 --- a/sharpd/sharp_zebra.h +++ b/sharpd/sharp_zebra.h @@ -24,7 +24,7 @@ extern void sharp_zebra_init(void); -extern void vrf_label_add(vrf_id_t vrf_id, mpls_label_t label); +extern void vrf_label_add(vrf_id_t vrf_id, afi_t afi, mpls_label_t label); extern void route_add(struct prefix *p, struct nexthop *nh); extern void route_delete(struct prefix *p); #endif diff --git a/zebra/zebra_vrf.h b/zebra/zebra_vrf.h index bfeb4b386c..d3a5316b9d 100644 --- a/zebra/zebra_vrf.h +++ b/zebra/zebra_vrf.h @@ -80,7 +80,7 @@ struct zebra_vrf { struct zebra_ns *zns; /* MPLS Label to handle L3VPN <-> vrf popping */ - mpls_label_t label; + mpls_label_t label[AFI_MAX]; /* MPLS static LSP config table */ struct hash *slsp_table; diff --git a/zebra/zserv.c b/zebra/zserv.c index 704b861960..ab8d8b51bc 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -2486,23 +2486,27 @@ stream_failure: return 1; } + static void zread_vrf_label(struct zserv *client, struct zebra_vrf *zvrf) { struct interface *ifp; mpls_label_t nlabel; + afi_t afi; struct stream *s; struct zebra_vrf *def_zvrf; enum lsp_types_t ltype; s = client->ibuf; STREAM_GETL(s, nlabel); - if (nlabel == zvrf->label) { + STREAM_GETC(s, afi); + if (nlabel == zvrf->label[afi]) { /* * Nothing to do here move along */ return; } + STREAM_GETC(s, ltype); if (zvrf->vrf->vrf_id != VRF_DEFAULT) @@ -2518,15 +2522,15 @@ static void zread_vrf_label(struct zserv *client, def_zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT); - if (zvrf->label != MPLS_LABEL_NONE) - mpls_lsp_uninstall(def_zvrf, ltype, zvrf->label, + if (zvrf->label[afi] != MPLS_LABEL_NONE) + mpls_lsp_uninstall(def_zvrf, ltype, zvrf->label[afi], NEXTHOP_TYPE_IFINDEX, NULL, ifp->ifindex); if (nlabel != MPLS_LABEL_NONE) mpls_lsp_install(def_zvrf, ltype, nlabel, MPLS_LABEL_IMPLICIT_NULL, NEXTHOP_TYPE_IFINDEX, NULL, ifp->ifindex); - zvrf->label = nlabel; + zvrf->label[afi] = nlabel; stream_failure: return; } From 8fd9db586f17d7034ad2ec1fd972e503c70349cb Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Thu, 15 Feb 2018 13:52:57 -0500 Subject: [PATCH 2/2] zebra: Ensure unconfiguration works properly for vrf labels If you were to configure a v4 and v6 vrf pop and forward label that both happened to be the same, unconfiguring one would remove them both. This fixes that issue by noticing if we should remove it or not based upon v4 or v6 having the same label or not. Signed-off-by: Donald Sharp --- zebra/zserv.c | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/zebra/zserv.c b/zebra/zserv.c index ab8d8b51bc..b3b1fa79e9 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -2522,9 +2522,29 @@ static void zread_vrf_label(struct zserv *client, def_zvrf = zebra_vrf_lookup_by_id(VRF_DEFAULT); - if (zvrf->label[afi] != MPLS_LABEL_NONE) - mpls_lsp_uninstall(def_zvrf, ltype, zvrf->label[afi], - NEXTHOP_TYPE_IFINDEX, NULL, ifp->ifindex); + if (zvrf->label[afi] != MPLS_LABEL_NONE) { + afi_t scrubber; + bool really_remove; + + really_remove = true; + for (scrubber = AFI_IP; scrubber < AFI_MAX ; scrubber++) { + if (scrubber == afi) + continue; + + if (zvrf->label[scrubber] == MPLS_LABEL_NONE) + continue; + + if (zvrf->label[afi] == zvrf->label[scrubber]) { + really_remove = false; + break; + } + } + + if (really_remove) + mpls_lsp_uninstall(def_zvrf, ltype, zvrf->label[afi], + NEXTHOP_TYPE_IFINDEX, NULL, + ifp->ifindex); + } if (nlabel != MPLS_LABEL_NONE) mpls_lsp_install(def_zvrf, ltype, nlabel, MPLS_LABEL_IMPLICIT_NULL,