diff options
-rw-r--r-- | lib/zclient.c | 3 | ||||
-rw-r--r-- | lib/zclient.h | 8 | ||||
-rw-r--r-- | sharpd/sharp_vty.c | 7 | ||||
-rw-r--r-- | sharpd/sharp_zebra.c | 4 | ||||
-rw-r--r-- | sharpd/sharp_zebra.h | 2 | ||||
-rw-r--r-- | zebra/zebra_vrf.h | 2 | ||||
-rw-r--r-- | zebra/zserv.c | 34 |
7 files changed, 47 insertions, 13 deletions
diff --git a/lib/zclient.c b/lib/zclient.c index 8e8b50b15..714888a3f 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 344b45fb5..d8a70c6cf 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 4f7d61b22..0e7d1f2c2 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 <ip$ipv4|ipv6$ipv6> 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 f771e53f0..78e8cf0ad 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 281c67ff9..0bba443bd 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 bfeb4b386..d3a5316b9 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 704b86196..b3b1fa79e 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,35 @@ 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, - 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, NEXTHOP_TYPE_IFINDEX, NULL, ifp->ifindex); - zvrf->label = nlabel; + zvrf->label[afi] = nlabel; stream_failure: return; } |