diff --git a/nest/route.h b/nest/route.h index bb0cb4a4..792f79dd 100644 --- a/nest/route.h +++ b/nest/route.h @@ -309,6 +309,8 @@ int rt_feed_channel(struct channel *c); void rt_feed_channel_abort(struct channel *c); struct rtable_config *rt_new_table(struct symbol *s, uint addr_type); +/* Default limit for ECMP next hops, defined in sysdep code */ +extern const int rt_default_ecmp; struct rt_show_data_rtable { node n; diff --git a/proto/bgp/config.Y b/proto/bgp/config.Y index 941ae5b6..0bd4c554 100644 --- a/proto/bgp/config.Y +++ b/proto/bgp/config.Y @@ -58,6 +58,7 @@ bgp_proto_start: proto_start BGP { BGP_CFG->gr_mode = BGP_GR_AWARE; BGP_CFG->gr_time = 120; BGP_CFG->setkey = 1; + BGP_CFG->check_link = 1; } ; diff --git a/proto/ospf/config.Y b/proto/ospf/config.Y index 98ddf5d0..04d5e2e9 100644 --- a/proto/ospf/config.Y +++ b/proto/ospf/config.Y @@ -219,6 +219,7 @@ ospf_proto_start: proto_start ospf_variant init_list(&OSPF_CFG->area_list); init_list(&OSPF_CFG->vlink_list); + OSPF_CFG->ecmp = rt_default_ecmp; OSPF_CFG->tick = OSPF_DEFAULT_TICK; OSPF_CFG->ospf2 = $2; OSPF_CFG->af_ext = !$2; @@ -461,6 +462,7 @@ ospf_iface_start: OSPF_PATT->deadc = DEADC_D; OSPF_PATT->type = OSPF_IT_UNDEF; init_list(&OSPF_PATT->nbma_list); + OSPF_PATT->check_link = 1; OSPF_PATT->ptp_netmask = 2; /* not specified */ OSPF_PATT->tx_tos = IP_PREC_INTERNET_CONTROL; OSPF_PATT->tx_priority = sk_priority_control; diff --git a/proto/rip/config.Y b/proto/rip/config.Y index e3bc4ae3..aff63f03 100644 --- a/proto/rip/config.Y +++ b/proto/rip/config.Y @@ -56,6 +56,7 @@ rip_proto_start: proto_start rip_variant init_list(&RIP_CFG->patt_list); RIP_CFG->rip2 = $2; + RIP_CFG->ecmp = rt_default_ecmp; RIP_CFG->infinity = RIP_DEFAULT_INFINITY; RIP_CFG->min_timeout_time = 60 S_; RIP_CFG->max_garbage_time = 60 S_; @@ -92,6 +93,7 @@ rip_iface_start: RIP_IFACE->split_horizon = 1; RIP_IFACE->poison_reverse = 1; RIP_IFACE->check_zero = 1; + RIP_IFACE->check_link = 1; RIP_IFACE->ttl_security = rip_cfg_is_v2() ? 0 : 1; RIP_IFACE->rx_buffer = rip_cfg_is_v2() ? RIP_MAX_PKT_LENGTH : 0; RIP_IFACE->tx_length = rip_cfg_is_v2() ? RIP_MAX_PKT_LENGTH : 0; diff --git a/sysdep/bsd/krt-sock.c b/sysdep/bsd/krt-sock.c index c36ae558..604cd510 100644 --- a/sysdep/bsd/krt-sock.c +++ b/sysdep/bsd/krt-sock.c @@ -33,6 +33,7 @@ #include "lib/string.h" #include "lib/socket.h" +const int rt_default_ecmp = 0; /* * There are significant differences in multiple tables support between BSD variants. @@ -145,9 +146,8 @@ krt_capable(rte *e) { rta *a = e->attrs; - /* XXXX device routes are broken */ return - ((a->dest == RTD_UNICAST && ipa_nonzero(a->nh.gw) && !a->nh.next) /* No multipath support */ + ((a->dest == RTD_UNICAST && !a->nh.next) /* No multipath support */ #ifdef RTF_REJECT || a->dest == RTD_UNREACHABLE #endif diff --git a/sysdep/linux/netlink.c b/sysdep/linux/netlink.c index 05c1fa8c..ca5c79a4 100644 --- a/sysdep/linux/netlink.c +++ b/sysdep/linux/netlink.c @@ -80,6 +80,8 @@ struct rtvia { #define krt_ecmp6(p) ((p)->af == AF_INET6) +const int rt_default_ecmp = 16; + /* * Structure nl_parse_state keeps state of received route processing. Ideally, * we could just independently parse received Netlink messages and immediately