zebra: identify MPLS FTNs by route type and instance

Use the route type and instance instead of the route distance
to identify MPLS FTNs. This is a more robust approach since the
routing daemons can modify the distance of their announced routes
via configuration, which can cause inconsistencies.

Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
This commit is contained in:
Renato Westphal 2019-08-08 13:56:39 -03:00
parent bad6b0e72e
commit e132dea064
13 changed files with 56 additions and 42 deletions

View file

@ -249,7 +249,7 @@ l2vpn_pw_init(struct l2vpn_pw *pw)
l2vpn_pw_fec(pw, &fec); l2vpn_pw_fec(pw, &fec);
lde_kernel_insert(&fec, AF_INET, (union ldpd_addr*)&pw->lsr_id, 0, 0, lde_kernel_insert(&fec, AF_INET, (union ldpd_addr*)&pw->lsr_id, 0, 0,
0, (void *)pw); 0, 0, (void *)pw);
lde_kernel_update(&fec); lde_kernel_update(&fec);
} }
@ -260,7 +260,7 @@ l2vpn_pw_exit(struct l2vpn_pw *pw)
struct zapi_pw zpw; struct zapi_pw zpw;
l2vpn_pw_fec(pw, &fec); l2vpn_pw_fec(pw, &fec);
lde_kernel_remove(&fec, AF_INET, (union ldpd_addr*)&pw->lsr_id, 0, 0); lde_kernel_remove(&fec, AF_INET, (union ldpd_addr*)&pw->lsr_id, 0, 0, 0);
lde_kernel_update(&fec); lde_kernel_update(&fec);
pw2zpw(pw, &zpw); pw2zpw(pw, &zpw);
@ -433,7 +433,7 @@ l2vpn_recv_pw_status(struct lde_nbr *ln, struct notify_msg *nm)
if (pw == NULL) if (pw == NULL)
return; return;
fnh = fec_nh_find(fn, AF_INET, (union ldpd_addr *)&ln->id, 0, 0); fnh = fec_nh_find(fn, AF_INET, (union ldpd_addr *)&ln->id, 0, 0, 0);
if (fnh == NULL) if (fnh == NULL)
return; return;
@ -482,7 +482,7 @@ l2vpn_recv_pw_status_wcard(struct lde_nbr *ln, struct notify_msg *nm)
} }
fnh = fec_nh_find(fn, AF_INET, (union ldpd_addr *)&ln->id, fnh = fec_nh_find(fn, AF_INET, (union ldpd_addr *)&ln->id,
0, 0); 0, 0, 0);
if (fnh == NULL) if (fnh == NULL)
continue; continue;

View file

@ -520,7 +520,8 @@ lde_dispatch_parent(struct thread *thread)
switch (imsg.hdr.type) { switch (imsg.hdr.type) {
case IMSG_NETWORK_ADD: case IMSG_NETWORK_ADD:
lde_kernel_insert(&fec, kr->af, &kr->nexthop, lde_kernel_insert(&fec, kr->af, &kr->nexthop,
kr->ifindex, kr->priority, kr->ifindex, kr->route_type,
kr->route_instance,
kr->flags & F_CONNECTED, NULL); kr->flags & F_CONNECTED, NULL);
break; break;
case IMSG_NETWORK_UPDATE: case IMSG_NETWORK_UPDATE:
@ -747,7 +748,8 @@ lde_send_change_klabel(struct fec_node *fn, struct fec_nh *fnh)
kr.ifindex = fnh->ifindex; kr.ifindex = fnh->ifindex;
kr.local_label = fn->local_label; kr.local_label = fn->local_label;
kr.remote_label = fnh->remote_label; kr.remote_label = fnh->remote_label;
kr.priority = fnh->priority; kr.route_type = fnh->route_type;
kr.route_instance = fnh->route_instance;
lde_imsg_compose_parent(IMSG_KLABEL_CHANGE, 0, &kr, lde_imsg_compose_parent(IMSG_KLABEL_CHANGE, 0, &kr,
sizeof(kr)); sizeof(kr));
@ -761,7 +763,8 @@ lde_send_change_klabel(struct fec_node *fn, struct fec_nh *fnh)
kr.ifindex = fnh->ifindex; kr.ifindex = fnh->ifindex;
kr.local_label = fn->local_label; kr.local_label = fn->local_label;
kr.remote_label = fnh->remote_label; kr.remote_label = fnh->remote_label;
kr.priority = fnh->priority; kr.route_type = fnh->route_type;
kr.route_instance = fnh->route_instance;
lde_imsg_compose_parent(IMSG_KLABEL_CHANGE, 0, &kr, lde_imsg_compose_parent(IMSG_KLABEL_CHANGE, 0, &kr,
sizeof(kr)); sizeof(kr));
@ -798,7 +801,8 @@ lde_send_delete_klabel(struct fec_node *fn, struct fec_nh *fnh)
kr.ifindex = fnh->ifindex; kr.ifindex = fnh->ifindex;
kr.local_label = fn->local_label; kr.local_label = fn->local_label;
kr.remote_label = fnh->remote_label; kr.remote_label = fnh->remote_label;
kr.priority = fnh->priority; kr.route_type = fnh->route_type;
kr.route_instance = fnh->route_instance;
lde_imsg_compose_parent(IMSG_KLABEL_DELETE, 0, &kr, lde_imsg_compose_parent(IMSG_KLABEL_DELETE, 0, &kr,
sizeof(kr)); sizeof(kr));
@ -812,7 +816,8 @@ lde_send_delete_klabel(struct fec_node *fn, struct fec_nh *fnh)
kr.ifindex = fnh->ifindex; kr.ifindex = fnh->ifindex;
kr.local_label = fn->local_label; kr.local_label = fn->local_label;
kr.remote_label = fnh->remote_label; kr.remote_label = fnh->remote_label;
kr.priority = fnh->priority; kr.route_type = fnh->route_type;
kr.route_instance = fnh->route_instance;
lde_imsg_compose_parent(IMSG_KLABEL_DELETE, 0, &kr, lde_imsg_compose_parent(IMSG_KLABEL_DELETE, 0, &kr,
sizeof(kr)); sizeof(kr));

View file

@ -108,7 +108,8 @@ struct fec_nh {
union ldpd_addr nexthop; union ldpd_addr nexthop;
ifindex_t ifindex; ifindex_t ifindex;
uint32_t remote_label; uint32_t remote_label;
uint8_t priority; uint8_t route_type;
unsigned short route_instance;
uint8_t flags; uint8_t flags;
}; };
#define F_FEC_NH_NEW 0x01 #define F_FEC_NH_NEW 0x01
@ -193,11 +194,11 @@ void rt_dump(pid_t);
void fec_snap(struct lde_nbr *); void fec_snap(struct lde_nbr *);
void fec_tree_clear(void); void fec_tree_clear(void);
struct fec_nh *fec_nh_find(struct fec_node *, int, union ldpd_addr *, struct fec_nh *fec_nh_find(struct fec_node *, int, union ldpd_addr *,
ifindex_t, uint8_t); ifindex_t, uint8_t, unsigned short);
void lde_kernel_insert(struct fec *, int, union ldpd_addr *, void lde_kernel_insert(struct fec *, int, union ldpd_addr *,
ifindex_t, uint8_t, int, void *); ifindex_t, uint8_t, unsigned short, int, void *);
void lde_kernel_remove(struct fec *, int, union ldpd_addr *, void lde_kernel_remove(struct fec *, int, union ldpd_addr *,
ifindex_t, uint8_t); ifindex_t, uint8_t, unsigned short);
void lde_kernel_update(struct fec *); void lde_kernel_update(struct fec *);
void lde_check_mapping(struct map *, struct lde_nbr *); void lde_check_mapping(struct map *, struct lde_nbr *);
void lde_check_request(struct map *, struct lde_nbr *); void lde_check_request(struct map *, struct lde_nbr *);

View file

@ -31,7 +31,7 @@ static int lde_nbr_is_nexthop(struct fec_node *,
static void fec_free(void *); static void fec_free(void *);
static struct fec_node *fec_add(struct fec *fec); static struct fec_node *fec_add(struct fec *fec);
static struct fec_nh *fec_nh_add(struct fec_node *, int, union ldpd_addr *, static struct fec_nh *fec_nh_add(struct fec_node *, int, union ldpd_addr *,
ifindex_t, uint8_t); ifindex_t, uint8_t, unsigned short);
static void fec_nh_del(struct fec_nh *); static void fec_nh_del(struct fec_nh *);
RB_GENERATE(fec_tree, fec, entry, fec_compare) RB_GENERATE(fec_tree, fec, entry, fec_compare)
@ -275,7 +275,7 @@ fec_add(struct fec *fec)
struct fec_nh * struct fec_nh *
fec_nh_find(struct fec_node *fn, int af, union ldpd_addr *nexthop, fec_nh_find(struct fec_node *fn, int af, union ldpd_addr *nexthop,
ifindex_t ifindex, uint8_t priority) ifindex_t ifindex, uint8_t route_type, unsigned short route_instance)
{ {
struct fec_nh *fnh; struct fec_nh *fnh;
@ -283,7 +283,8 @@ fec_nh_find(struct fec_node *fn, int af, union ldpd_addr *nexthop,
if (fnh->af == af && if (fnh->af == af &&
ldp_addrcmp(af, &fnh->nexthop, nexthop) == 0 && ldp_addrcmp(af, &fnh->nexthop, nexthop) == 0 &&
fnh->ifindex == ifindex && fnh->ifindex == ifindex &&
fnh->priority == priority) fnh->route_type == route_type &&
fnh->route_instance == route_instance)
return (fnh); return (fnh);
return (NULL); return (NULL);
@ -291,7 +292,7 @@ fec_nh_find(struct fec_node *fn, int af, union ldpd_addr *nexthop,
static struct fec_nh * static struct fec_nh *
fec_nh_add(struct fec_node *fn, int af, union ldpd_addr *nexthop, fec_nh_add(struct fec_node *fn, int af, union ldpd_addr *nexthop,
ifindex_t ifindex, uint8_t priority) ifindex_t ifindex, uint8_t route_type, unsigned short route_instance)
{ {
struct fec_nh *fnh; struct fec_nh *fnh;
@ -303,7 +304,8 @@ fec_nh_add(struct fec_node *fn, int af, union ldpd_addr *nexthop,
fnh->nexthop = *nexthop; fnh->nexthop = *nexthop;
fnh->ifindex = ifindex; fnh->ifindex = ifindex;
fnh->remote_label = NO_LABEL; fnh->remote_label = NO_LABEL;
fnh->priority = priority; fnh->route_type = route_type;
fnh->route_instance = route_instance;
LIST_INSERT_HEAD(&fn->nexthops, fnh, entry); LIST_INSERT_HEAD(&fn->nexthops, fnh, entry);
return (fnh); return (fnh);
@ -318,7 +320,8 @@ fec_nh_del(struct fec_nh *fnh)
void void
lde_kernel_insert(struct fec *fec, int af, union ldpd_addr *nexthop, lde_kernel_insert(struct fec *fec, int af, union ldpd_addr *nexthop,
ifindex_t ifindex, uint8_t priority, int connected, void *data) ifindex_t ifindex, uint8_t route_type, unsigned short route_instance,
int connected, void *data)
{ {
struct fec_node *fn; struct fec_node *fn;
struct fec_nh *fnh; struct fec_nh *fnh;
@ -329,9 +332,10 @@ lde_kernel_insert(struct fec *fec, int af, union ldpd_addr *nexthop,
if (data) if (data)
fn->data = data; fn->data = data;
fnh = fec_nh_find(fn, af, nexthop, ifindex, priority); fnh = fec_nh_find(fn, af, nexthop, ifindex, route_type, route_instance);
if (fnh == NULL) if (fnh == NULL)
fnh = fec_nh_add(fn, af, nexthop, ifindex, priority); fnh = fec_nh_add(fn, af, nexthop, ifindex, route_type,
route_instance);
fnh->flags |= F_FEC_NH_NEW; fnh->flags |= F_FEC_NH_NEW;
if (connected) if (connected)
fnh->flags |= F_FEC_NH_CONNECTED; fnh->flags |= F_FEC_NH_CONNECTED;
@ -339,7 +343,7 @@ lde_kernel_insert(struct fec *fec, int af, union ldpd_addr *nexthop,
void void
lde_kernel_remove(struct fec *fec, int af, union ldpd_addr *nexthop, lde_kernel_remove(struct fec *fec, int af, union ldpd_addr *nexthop,
ifindex_t ifindex, uint8_t priority) ifindex_t ifindex, uint8_t route_type, unsigned short route_instance)
{ {
struct fec_node *fn; struct fec_node *fn;
struct fec_nh *fnh; struct fec_nh *fnh;
@ -348,7 +352,7 @@ lde_kernel_remove(struct fec *fec, int af, union ldpd_addr *nexthop,
if (fn == NULL) if (fn == NULL)
/* route lost */ /* route lost */
return; return;
fnh = fec_nh_find(fn, af, nexthop, ifindex, priority); fnh = fec_nh_find(fn, af, nexthop, ifindex, route_type, route_instance);
if (fnh == NULL) if (fnh == NULL)
/* route lost */ /* route lost */
return; return;

View file

@ -136,7 +136,8 @@ ldp_zebra_send_mpls_labels(int cmd, struct kroute *kr)
fatalx("kr_change: unknown af"); fatalx("kr_change: unknown af");
} }
zl.ifindex = kr->ifindex; zl.ifindex = kr->ifindex;
zl.distance = kr->priority; zl.route_type = kr->route_type;
zl.route_instance = kr->route_instance;
zl.local_label = kr->local_label; zl.local_label = kr->local_label;
zl.remote_label = kr->remote_label; zl.remote_label = kr->remote_label;
@ -398,7 +399,8 @@ ldp_zebra_read_route(ZAPI_CALLBACK_ARGS)
break; break;
} }
kr.prefixlen = api.prefix.prefixlen; kr.prefixlen = api.prefix.prefixlen;
kr.priority = api.distance; kr.route_type = api.type;
kr.route_instance = api.instance;
switch (api.type) { switch (api.type) {
case ZEBRA_ROUTE_CONNECT: case ZEBRA_ROUTE_CONNECT:

View file

@ -543,7 +543,8 @@ struct kroute {
uint32_t local_label; uint32_t local_label;
uint32_t remote_label; uint32_t remote_label;
unsigned short ifindex; unsigned short ifindex;
uint8_t priority; uint8_t route_type;
uint8_t route_instance;
uint16_t flags; uint16_t flags;
}; };

View file

@ -2479,7 +2479,8 @@ int zapi_labels_encode(struct stream *s, int cmd, struct zapi_labels *zl)
return -1; return -1;
} }
stream_putl(s, zl->ifindex); stream_putl(s, zl->ifindex);
stream_putc(s, zl->distance); stream_putc(s, zl->route_type);
stream_putw(s, zl->route_instance);
stream_putl(s, zl->local_label); stream_putl(s, zl->local_label);
stream_putl(s, zl->remote_label); stream_putl(s, zl->remote_label);
@ -2528,7 +2529,8 @@ int zapi_labels_decode(struct stream *s, struct zapi_labels *zl)
return -1; return -1;
} }
STREAM_GETL(s, zl->ifindex); STREAM_GETL(s, zl->ifindex);
STREAM_GETC(s, zl->distance); STREAM_GETC(s, zl->route_type);
STREAM_GETW(s, zl->route_instance);
STREAM_GETL(s, zl->local_label); STREAM_GETL(s, zl->local_label);
STREAM_GETL(s, zl->remote_label); STREAM_GETL(s, zl->remote_label);

View file

@ -400,7 +400,8 @@ struct zapi_labels {
struct prefix prefix; struct prefix prefix;
union g_addr nexthop; union g_addr nexthop;
ifindex_t ifindex; ifindex_t ifindex;
uint8_t distance; uint8_t route_type;
unsigned short route_instance;
mpls_label_t local_label; mpls_label_t local_label;
mpls_label_t remote_label; mpls_label_t remote_label;
}; };

View file

@ -623,7 +623,8 @@ static int ospf_zebra_send_mpls_labels(int cmd, struct sr_nhlfe nhlfe)
zl.prefix.u.prefix4 = nhlfe.prefv4.prefix; zl.prefix.u.prefix4 = nhlfe.prefv4.prefix;
zl.nexthop.ipv4 = nhlfe.nexthop; zl.nexthop.ipv4 = nhlfe.nexthop;
zl.ifindex = nhlfe.ifindex; zl.ifindex = nhlfe.ifindex;
zl.distance = OSPF_SR_PRIORITY_DEFAULT; zl.route_type = ZEBRA_ROUTE_OSPF;
zl.route_instance = 0;
zl.local_label = nhlfe.label_in; zl.local_label = nhlfe.label_in;
zl.remote_label = nhlfe.label_out; zl.remote_label = nhlfe.label_out;

View file

@ -27,9 +27,6 @@
#ifndef _FRR_OSPF_SR_H #ifndef _FRR_OSPF_SR_H
#define _FRR_OSPF_SR_H #define _FRR_OSPF_SR_H
/* Default Route priority for OSPF Segment Routing */
#define OSPF_SR_PRIORITY_DEFAULT 10
/* macros and constants for segment routing */ /* macros and constants for segment routing */
#define SET_RANGE_SIZE_MASK 0xffffff00 #define SET_RANGE_SIZE_MASK 0xffffff00
#define GET_RANGE_SIZE_MASK 0x00ffffff #define GET_RANGE_SIZE_MASK 0x00ffffff

View file

@ -1788,14 +1788,14 @@ static void zread_mpls_labels(ZAPI_HANDLER_ARGS)
mpls_lsp_install(zvrf, zl.type, zl.local_label, zl.remote_label, mpls_lsp_install(zvrf, zl.type, zl.local_label, zl.remote_label,
gtype, &zl.nexthop, zl.ifindex); gtype, &zl.nexthop, zl.ifindex);
mpls_ftn_update(1, zvrf, zl.type, &zl.prefix, gtype, mpls_ftn_update(1, zvrf, zl.type, &zl.prefix, gtype,
&zl.nexthop, zl.ifindex, zl.distance, &zl.nexthop, zl.ifindex, zl.route_type,
zl.remote_label); zl.route_instance, zl.remote_label);
} else if (hdr->command == ZEBRA_MPLS_LABELS_DELETE) { } else if (hdr->command == ZEBRA_MPLS_LABELS_DELETE) {
mpls_lsp_uninstall(zvrf, zl.type, zl.local_label, gtype, mpls_lsp_uninstall(zvrf, zl.type, zl.local_label, gtype,
&zl.nexthop, zl.ifindex); &zl.nexthop, zl.ifindex);
mpls_ftn_update(0, zvrf, zl.type, &zl.prefix, gtype, mpls_ftn_update(0, zvrf, zl.type, &zl.prefix, gtype,
&zl.nexthop, zl.ifindex, zl.distance, &zl.nexthop, zl.ifindex, zl.route_type,
zl.remote_label); zl.route_instance, zl.remote_label);
} }
} }

View file

@ -2542,8 +2542,8 @@ static bool mpls_ftn_update_nexthop(int add, struct nexthop *nexthop,
*/ */
int mpls_ftn_update(int add, struct zebra_vrf *zvrf, enum lsp_types_t type, int mpls_ftn_update(int add, struct zebra_vrf *zvrf, enum lsp_types_t type,
struct prefix *prefix, enum nexthop_types_t gtype, struct prefix *prefix, enum nexthop_types_t gtype,
union g_addr *gate, ifindex_t ifindex, uint8_t distance, union g_addr *gate, ifindex_t ifindex, uint8_t route_type,
mpls_label_t out_label) unsigned short route_instance, mpls_label_t out_label)
{ {
struct route_table *table; struct route_table *table;
struct route_node *rn; struct route_node *rn;
@ -2562,7 +2562,7 @@ int mpls_ftn_update(int add, struct zebra_vrf *zvrf, enum lsp_types_t type,
RNODE_FOREACH_RE (rn, re) { RNODE_FOREACH_RE (rn, re) {
if (CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED)) if (CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED))
continue; continue;
if (re->distance == distance) if (re->type == route_type && re->instance == route_instance)
break; break;
} }

View file

@ -269,8 +269,8 @@ void zebra_mpls_print_fec(struct vty *vty, struct zebra_vrf *zvrf,
*/ */
int mpls_ftn_update(int add, struct zebra_vrf *zvrf, enum lsp_types_t type, int mpls_ftn_update(int add, struct zebra_vrf *zvrf, enum lsp_types_t type,
struct prefix *prefix, enum nexthop_types_t gtype, struct prefix *prefix, enum nexthop_types_t gtype,
union g_addr *gate, ifindex_t ifindex, uint8_t distance, union g_addr *gate, ifindex_t ifindex, uint8_t route_type,
mpls_label_t out_label); unsigned short route_instance, mpls_label_t out_label);
/* /*
* Install/update a NHLFE for an LSP in the forwarding table. This may be * Install/update a NHLFE for an LSP in the forwarding table. This may be