Merge pull request #1911 from donaldsharp/mpls_love

Mpls love
This commit is contained in:
Renato Westphal 2018-03-19 08:37:13 -03:00 committed by GitHub
commit d6716be3d9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 163 additions and 26 deletions

View File

@ -1340,6 +1340,16 @@ bool zapi_nexthop_update_decode(struct stream *s, struct zapi_route *nhr)
case NEXTHOP_TYPE_BLACKHOLE:
break;
}
STREAM_GETC(s, nhr->nexthops[i].label_num);
if (nhr->nexthops[i].label_num > MPLS_MAX_LABELS) {
zlog_warn("%s: invalid number of MPLS labels (%u)",
__func__, nhr->nexthops[i].label_num);
return false;
}
if (nhr->nexthops[i].label_num)
STREAM_GET(&nhr->nexthops[i].labels[0], s,
nhr->nexthops[i].label_num
* sizeof(mpls_label_t));
}
return true;

View File

@ -39,6 +39,46 @@ extern uint32_t total_routes;
extern uint32_t installed_routes;
extern uint32_t removed_routes;
DEFPY(watch_nexthop_v6, watch_nexthop_v6_cmd,
"sharp watch nexthop X:X::X:X$nhop",
"Sharp routing Protocol\n"
"Watch for changes\n"
"Watch for nexthop changes\n"
"The v6 nexthop to signal for watching\n")
{
struct prefix p;
memset(&p, 0, sizeof(p));
p.prefixlen = 128;
memcpy(&p.u.prefix6, &nhop, 16);
p.family = AF_INET6;
sharp_zebra_nexthop_watch(&p, true);
return CMD_SUCCESS;
}
DEFPY(watch_nexthop_v4, watch_nexthop_v4_cmd,
"sharp watch nexthop A.B.C.D$nhop",
"Sharp routing Protocol\n"
"Watch for changes\n"
"Watch for nexthop changes\n"
"The v4 nexthop to signal for watching\n")
{
struct prefix p;
memset(&p, 0, sizeof(p));
p.prefixlen = 32;
p.u.prefix4 = nhop;
p.family = AF_INET;
sharp_zebra_nexthop_watch(&p, true);
return CMD_SUCCESS;
}
DEFPY (install_routes,
install_routes_cmd,
"sharp install routes A.B.C.D$start nexthop A.B.C.D$nexthop (1-1000000)$routes",
@ -147,5 +187,7 @@ void sharp_vty_init(void)
install_element(ENABLE_NODE, &install_routes_cmd);
install_element(ENABLE_NODE, &remove_routes_cmd);
install_element(ENABLE_NODE, &vrf_label_cmd);
install_element(ENABLE_NODE, &watch_nexthop_v6_cmd);
install_element(ENABLE_NODE, &watch_nexthop_v4_cmd);
return;
}

View File

@ -214,6 +214,65 @@ void route_delete(struct prefix *p)
return;
}
void sharp_zebra_nexthop_watch(struct prefix *p, bool watch)
{
int command = ZEBRA_NEXTHOP_REGISTER;
if (!watch)
command = ZEBRA_NEXTHOP_UNREGISTER;
zclient_send_rnh(zclient, command, p, true, VRF_DEFAULT);
}
static int sharp_nexthop_update(int command, struct zclient *zclient,
zebra_size_t length, vrf_id_t vrf_id)
{
struct zapi_route nhr;
char buf[PREFIX_STRLEN];
int i;
if (!zapi_nexthop_update_decode(zclient->ibuf, &nhr)) {
zlog_warn("%s: Decode of update failed", __PRETTY_FUNCTION__);
return 0;
}
zlog_debug("Received update for %s",
prefix2str(&nhr.prefix, buf, sizeof(buf)));
for (i = 0; i < nhr.nexthop_num; i++) {
struct zapi_nexthop *znh = &nhr.nexthops[i];
switch (znh->type) {
case NEXTHOP_TYPE_IPV4_IFINDEX:
case NEXTHOP_TYPE_IPV4:
zlog_debug(
"\tNexthop %s, type: %d, ifindex: %d, vrf: %d, label_num: %d",
inet_ntop(AF_INET, &znh->gate.ipv4.s_addr, buf,
sizeof(buf)),
znh->type, znh->ifindex, znh->vrf_id,
znh->label_num);
break;
case NEXTHOP_TYPE_IPV6_IFINDEX:
case NEXTHOP_TYPE_IPV6:
zlog_debug(
"\tNexthop %s, type: %d, ifindex: %d, vrf: %d, label_num: %d",
inet_ntop(AF_INET6, &znh->gate.ipv6, buf,
sizeof(buf)),
znh->type, znh->ifindex, znh->vrf_id,
znh->label_num);
break;
case NEXTHOP_TYPE_IFINDEX:
zlog_debug("\tNexthop IFINDEX: %d, ifindex: %d",
znh->type, znh->ifindex);
break;
case NEXTHOP_TYPE_BLACKHOLE:
zlog_debug("\tNexthop blackhole");
break;
}
}
return 0;
}
extern struct zebra_privs_t sharp_privs;
void sharp_zebra_init(void)
@ -231,4 +290,5 @@ void sharp_zebra_init(void)
zclient->interface_address_add = interface_address_add;
zclient->interface_address_delete = interface_address_delete;
zclient->route_notify_owner = route_notify_owner;
zclient->nexthop_update = sharp_nexthop_update;
}

View File

@ -27,4 +27,5 @@ extern void sharp_zebra_init(void);
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);
extern void sharp_zebra_nexthop_watch(struct prefix *p, bool watch);
#endif

View File

@ -2254,6 +2254,19 @@ void zebra_mpls_print_fec(struct vty *vty, struct zebra_vrf *zvrf,
fec_print(rn->info, vty);
}
static bool mpls_ftn_update_nexthop(int add, struct nexthop *nexthop,
enum lsp_types_t type, mpls_label_t label)
{
if (add && nexthop->nh_label_type == ZEBRA_LSP_NONE)
nexthop_add_labels(nexthop, type, 1, &label);
else if (!add && nexthop->nh_label_type == type)
nexthop_del_labels(nexthop);
else
return false;
return true;
}
/*
* Install/uninstall a FEC-To-NHLFE (FTN) binding.
*/
@ -2266,6 +2279,7 @@ int mpls_ftn_update(int add, struct zebra_vrf *zvrf, enum lsp_types_t type,
struct route_node *rn;
struct route_entry *re;
struct nexthop *nexthop;
bool found;
/* Lookup table. */
table = zebra_vrf_table(family2afi(prefix->family), SAFI_UNICAST,
@ -2285,6 +2299,7 @@ int mpls_ftn_update(int add, struct zebra_vrf *zvrf, enum lsp_types_t type,
if (re == NULL)
return -1;
found = false;
for (nexthop = re->ng.nexthop; nexthop; nexthop = nexthop->next) {
switch (nexthop->type) {
case NEXTHOP_TYPE_IPV4:
@ -2297,7 +2312,11 @@ int mpls_ftn_update(int add, struct zebra_vrf *zvrf, enum lsp_types_t type,
if (nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX
&& nexthop->ifindex != ifindex)
continue;
goto found;
if (!mpls_ftn_update_nexthop(add, nexthop, type,
out_label))
return 0;
found = true;
break;
case NEXTHOP_TYPE_IPV6:
case NEXTHOP_TYPE_IPV6_IFINDEX:
if (gtype != NEXTHOP_TYPE_IPV6
@ -2308,21 +2327,18 @@ int mpls_ftn_update(int add, struct zebra_vrf *zvrf, enum lsp_types_t type,
if (nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX
&& nexthop->ifindex != ifindex)
continue;
goto found;
if (!mpls_ftn_update_nexthop(add, nexthop, type,
out_label))
return 0;
found = true;
break;
default:
break;
}
}
/* nexthop not found */
return -1;
found:
if (add && nexthop->nh_label_type == ZEBRA_LSP_NONE)
nexthop_add_labels(nexthop, type, 1, &out_label);
else if (!add && nexthop->nh_label_type == type)
nexthop_del_labels(nexthop);
else
return 0;
if (!found)
return -1;
SET_FLAG(re->status, ROUTE_ENTRY_CHANGED);
SET_FLAG(re->status, ROUTE_ENTRY_LABELS_CHANGED);

View File

@ -986,7 +986,7 @@ static int send_client(struct rnh *rnh, struct zserv *client, rnh_type_t type,
struct route_entry *re;
unsigned long nump;
u_char num;
struct nexthop *nexthop;
struct nexthop *nh;
struct route_node *rn;
int cmd = (type == RNH_IMPORT_CHECK_TYPE) ? ZEBRA_IMPORT_CHECK_UPDATE
: ZEBRA_NEXTHOP_UPDATE;
@ -1022,32 +1022,40 @@ static int send_client(struct rnh *rnh, struct zserv *client, rnh_type_t type,
num = 0;
nump = stream_get_endp(s);
stream_putc(s, 0);
for (nexthop = re->ng.nexthop; nexthop; nexthop = nexthop->next)
if ((CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)
|| CHECK_FLAG(nexthop->flags,
NEXTHOP_FLAG_RECURSIVE))
&& CHECK_FLAG(nexthop->flags,
NEXTHOP_FLAG_ACTIVE)) {
stream_putc(s, nexthop->type);
switch (nexthop->type) {
for (nh = re->ng.nexthop; nh; nh = nh->next)
if ((CHECK_FLAG(nh->flags, NEXTHOP_FLAG_FIB)
|| CHECK_FLAG(nh->flags, NEXTHOP_FLAG_RECURSIVE))
&& CHECK_FLAG(nh->flags, NEXTHOP_FLAG_ACTIVE)) {
stream_putc(s, nh->type);
switch (nh->type) {
case NEXTHOP_TYPE_IPV4:
case NEXTHOP_TYPE_IPV4_IFINDEX:
stream_put_in_addr(s,
&nexthop->gate.ipv4);
stream_putl(s, nexthop->ifindex);
stream_put_in_addr(s, &nh->gate.ipv4);
stream_putl(s, nh->ifindex);
break;
case NEXTHOP_TYPE_IFINDEX:
stream_putl(s, nexthop->ifindex);
stream_putl(s, nh->ifindex);
break;
case NEXTHOP_TYPE_IPV6:
case NEXTHOP_TYPE_IPV6_IFINDEX:
stream_put(s, &nexthop->gate.ipv6, 16);
stream_putl(s, nexthop->ifindex);
stream_put(s, &nh->gate.ipv6, 16);
stream_putl(s, nh->ifindex);
break;
default:
/* do nothing */
break;
}
if (nh->nh_label) {
stream_putc(s,
nh->nh_label->num_labels);
if (nh->nh_label->num_labels)
stream_put(
s,
&nh->nh_label->label[0],
nh->nh_label->num_labels
* sizeof(mpls_label_t));
} else
stream_putc(s, 0);
num++;
}
stream_putc_at(s, nump, num);