mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-15 09:20:25 +00:00
Merge pull request #1213 from opensourcerouting/zebra-netlink
Misc RIB/Netlink fixes
This commit is contained in:
commit
5176f7b713
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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. */
|
||||
|
Loading…
Reference in New Issue
Block a user