Merge pull request #1213 from opensourcerouting/zebra-netlink

Misc RIB/Netlink fixes
This commit is contained in:
Donald Sharp 2017-09-25 14:33:14 -04:00 committed by GitHub
commit 5176f7b713
4 changed files with 56 additions and 110 deletions

View File

@ -57,7 +57,8 @@ pid_t pid_output(const char *path)
lock.l_whence = SEEK_SET;
if (fcntl(fd, F_SETLK, &lock) < 0) {
zlog_err("Could not lock pid_file %s, exiting", path);
zlog_err("Could not lock pid_file %s (%s), exiting",
path, safe_strerror(errno));
exit(1);
}

View File

@ -526,7 +526,7 @@ static int netlink_route_change_read_unicast(struct sockaddr_nl *snl,
if (re->nexthop_num == 0)
XFREE(MTYPE_RE, re);
else
rib_add_multipath(AFI_IP, SAFI_UNICAST, &p,
rib_add_multipath(afi, SAFI_UNICAST, &p,
NULL, re);
}
} else {
@ -1446,8 +1446,8 @@ static int netlink_route_multipath(int cmd, struct prefix *p,
&& CHECK_FLAG(nexthop->flags,
NEXTHOP_FLAG_FIB))) {
routedesc = nexthop->rparent
? "recursive, 1 hop"
: "single hop";
? "recursive, single-path"
: "single-path";
_netlink_route_debug(cmd, p, nexthop, routedesc,
family, zvrf);
@ -1529,8 +1529,8 @@ static int netlink_route_multipath(int cmd, struct prefix *p,
&& CHECK_FLAG(nexthop->flags,
NEXTHOP_FLAG_FIB))) {
routedesc = nexthop->rparent
? "recursive, multihop"
: "multihop";
? "recursive, multipath"
: "multipath";
nexthop_num++;
_netlink_route_debug(cmd, p, nexthop, routedesc,
@ -2349,6 +2349,7 @@ int netlink_mpls_multipath(int cmd, zebra_lsp_t *lsp)
unsigned int nexthop_num;
const char *routedesc;
struct zebra_ns *zns = zebra_ns_lookup(NS_DEFAULT);
int route_type;
struct {
struct nlmsghdr n;
@ -2382,9 +2383,11 @@ int netlink_mpls_multipath(int cmd, zebra_lsp_t *lsp)
}
}
if (nexthop_num == 0) // unexpected
if (nexthop_num == 0 || !lsp->best_nhlfe) // unexpected
return 0;
route_type = re_type_from_lsp_type(lsp->best_nhlfe->type);
req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));
req.n.nlmsg_flags = NLM_F_CREATE | NLM_F_REQUEST;
req.n.nlmsg_type = cmd;
@ -2393,7 +2396,7 @@ int netlink_mpls_multipath(int cmd, zebra_lsp_t *lsp)
req.r.rtm_family = AF_MPLS;
req.r.rtm_table = RT_TABLE_MAIN;
req.r.rtm_dst_len = MPLS_LABEL_LEN_BITS;
req.r.rtm_protocol = RTPROT_ZEBRA;
req.r.rtm_protocol = zebra2proto(route_type);
req.r.rtm_scope = RT_SCOPE_UNIVERSE;
req.r.rtm_type = RTN_UNICAST;
@ -2409,7 +2412,7 @@ int netlink_mpls_multipath(int cmd, zebra_lsp_t *lsp)
* chosen depend on the operation.
*/
if (nexthop_num == 1 || multipath_num == 1) {
routedesc = "single hop";
routedesc = "single-path";
_netlink_mpls_debug(cmd, lsp->ile.in_label, routedesc);
nexthop_num = 0;
@ -2457,7 +2460,7 @@ int netlink_mpls_multipath(int cmd, zebra_lsp_t *lsp)
rta->rta_len = RTA_LENGTH(0);
rtnh = RTA_DATA(rta);
routedesc = "multihop";
routedesc = "multipath";
_netlink_mpls_debug(cmd, lsp->ile.in_label, routedesc);
nexthop_num = 0;

View File

@ -436,6 +436,24 @@ static inline enum lsp_types_t lsp_type_from_re_type(int re_type)
}
}
/*
* Map LSP type to RIB type.
*/
static inline int re_type_from_lsp_type(enum lsp_types_t lsp_type)
{
switch (lsp_type) {
case ZEBRA_LSP_STATIC:
return ZEBRA_ROUTE_STATIC;
case ZEBRA_LSP_LDP:
return ZEBRA_ROUTE_LDP;
case ZEBRA_LSP_BGP:
return ZEBRA_ROUTE_BGP;
case ZEBRA_LSP_NONE:
default:
return ZEBRA_ROUTE_KERNEL;
}
}
/* NHLFE type as printable string. */
static inline const char *nhlfe_type2str(enum lsp_types_t lsp_type)
{

View File

@ -2216,23 +2216,18 @@ int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p,
struct route_entry *same;
struct nexthop *nexthop;
int ret = 0;
int family;
if (!re)
return 0;
if (p->family == AF_INET)
family = AFI_IP;
else
family = AFI_IP6;
assert(!src_p || family == AFI_IP6);
assert(!src_p || afi == AFI_IP6);
/* Lookup table. */
table = zebra_vrf_table_with_table_id(family, safi, re->vrf_id,
re->table);
if (!table)
table = zebra_vrf_table_with_table_id(afi, safi, re->vrf_id, re->table);
if (!table) {
XFREE(MTYPE_RE, re);
return 0;
}
/* Make it sure prefixlen is applied to the prefix. */
apply_mask(p);
@ -2258,8 +2253,18 @@ int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p,
if (CHECK_FLAG(same->status, ROUTE_ENTRY_REMOVED))
continue;
if (same->type == re->type && same->instance == re->instance
&& same->table == re->table && !RIB_SYSTEM_ROUTE(same))
if (same->type != re->type)
continue;
if (same->instance != re->instance)
continue;
if (same->type == ZEBRA_ROUTE_KERNEL &&
same->metric != re->metric)
continue;
/*
* We should allow duplicate connected routes because of
* IPv6 link-local routes and unnumbered interfaces on Linux.
*/
if (same->type != ZEBRA_ROUTE_CONNECT)
break;
}
@ -2437,70 +2442,10 @@ int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance,
u_int32_t mtu, u_char distance)
{
struct route_entry *re;
struct route_entry *same = NULL;
struct route_table *table;
struct route_node *rn;
struct nexthop *rtnh;
struct nexthop *nexthop;
assert(!src_p || afi == AFI_IP6);
/* Lookup table. */
table = zebra_vrf_table_with_table_id(afi, safi, vrf_id, table_id);
if (!table)
return 0;
/* Make sure mask is applied. */
apply_mask(p);
if (src_p)
apply_mask_ipv6(src_p);
/* Set default distance by route type. */
if (distance == 0) {
distance = route_distance(type);
/* iBGP distance is 200. */
if (type == ZEBRA_ROUTE_BGP
&& CHECK_FLAG(flags, ZEBRA_FLAG_IBGP))
distance = 200;
}
/* Lookup route node.*/
rn = srcdest_rnode_get(table, p, src_p);
/* If same type of route are installed, treat it as a implicit
withdraw. */
RNODE_FOREACH_RE (rn, re) {
if (CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED))
continue;
if (re->type != type)
continue;
if (re->instance != instance)
continue;
if (re->type == ZEBRA_ROUTE_KERNEL &&
re->metric != metric)
continue;
if (!RIB_SYSTEM_ROUTE(re)) {
same = re;
break;
}
/* Duplicate system route comes in. */
rtnh = re->nexthop;
if (nexthop_same_no_recurse(rtnh, nh))
return 0;
/*
* Nexthop is different. Remove the old route unless it's
* a connected route. This exception is necessary because
* of IPv6 link-local routes and unnumbered interfaces on
* Linux.
*/
else if (type != ZEBRA_ROUTE_CONNECT)
same = re;
}
/* Allocate new re structure. */
/* Allocate new route_entry structure. */
re = XCALLOC(MTYPE_RE, sizeof(struct route_entry));
re->type = type;
re->instance = instance;
re->distance = distance;
@ -2512,33 +2457,12 @@ int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type, u_short instance,
re->nexthop_num = 0;
re->uptime = time(NULL);
rtnh = nexthop_new();
*rtnh = *nh;
route_entry_nexthop_add(re, rtnh);
/* Add nexthop. */
nexthop = nexthop_new();
*nexthop = *nh;
route_entry_nexthop_add(re, nexthop);
/* If this route is kernel route, set FIB flag to the route. */
if (RIB_SYSTEM_ROUTE(re))
for (rtnh = re->nexthop; rtnh; rtnh = rtnh->next)
SET_FLAG(rtnh->flags, NEXTHOP_FLAG_FIB);
/* Link new rib to node.*/
if (IS_ZEBRA_DEBUG_RIB) {
rnode_debug(
rn, vrf_id,
"Inserting route rn %p, re %p (type %d) existing %p",
(void *)rn, (void *)re, re->type, (void *)same);
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
route_entry_dump(p, src_p, re);
}
rib_addnode(rn, re, 1);
/* Free implicit route.*/
if (same)
rib_delnode(rn, same);
route_unlock_node(rn);
return 0;
return rib_add_multipath(afi, safi, p, src_p, re);
}
/* Schedule routes of a particular table (address-family) based on event. */