routefilter currently filters the default route, if it's priority is higher than the filter prio.
This might not be a good idea - for example you might want to redistribute a default route into ospf, for that you need it in the routing table but it is configured with a low priority (high value) as a route of last resort or maybe even as a reject/blackhole. Treat the default route as a special case and always pass it. ok? diff --git sys/net/rtsock.c sys/net/rtsock.c index 70497d29a93..2e94fdbc0b1 100644 --- sys/net/rtsock.c +++ sys/net/rtsock.c @@ -110,7 +110,9 @@ int route_output(struct mbuf *, struct socket *, struct sockaddr *, int route_ctloutput(int, struct socket *, int, int, struct mbuf *); int route_usrreq(struct socket *, int, struct mbuf *, struct mbuf *, struct mbuf *, struct proc *); -void route_input(struct mbuf *m0, struct socket *, sa_family_t); +int route_is_default(struct sockaddr *, struct sockaddr *); +void route_input(struct mbuf *m0, struct socket *, struct rt_addrinfo *, + sa_family_t); int route_arp_conflict(struct rtentry *, struct rt_addrinfo *); int route_cleargateway(struct rtentry *, void *, unsigned int); void route_senddesync(void *); @@ -403,8 +405,33 @@ route_senddesync(void *data) timeout_add(&rop->timeout, ROUTE_DESYNC_RESEND_TIMEOUT); } +int +route_is_default(struct sockaddr *dst, struct sockaddr *mask) +{ + /* see if.c if_group_routechange() */ + switch (dst->sa_family) { + case AF_INET: + if (satosin(dst)->sin_addr.s_addr == INADDR_ANY && + mask && (mask->sa_len == 0 || + satosin(mask)->sin_addr.s_addr == INADDR_ANY)) + return (1); + break; +#ifdef INET6 + case AF_INET6: + if (IN6_ARE_ADDR_EQUAL(&(satosin6(dst))->sin6_addr, + &in6addr_any) && mask && (mask->sa_len == 0 || + IN6_ARE_ADDR_EQUAL(&(satosin6(mask))->sin6_addr, + &in6addr_any))) + return (1); + break; +#endif + } + return (0); +} + void -route_input(struct mbuf *m0, struct socket *so, sa_family_t sa_family) +route_input(struct mbuf *m0, struct socket *so, struct rt_addrinfo *info, + sa_family_t sa_family) { struct routecb *rop; struct rawcb *rp; @@ -447,8 +474,16 @@ route_input(struct mbuf *m0, struct socket *so, sa_family_t sa_family) if (rtm->rtm_type != RTM_DESYNC && rop->msgfilter != 0 && !(rop->msgfilter & (1 << rtm->rtm_type))) continue; - if (rop->priority != 0 && rop->priority < rtm->rtm_priority) - continue; + /* priority filter */ + if (rop->priority != 0) + if ((info == NULL && + rop->priority < rtm->rtm_priority) || + (info != NULL && + !route_is_default(info->rti_info[RTAX_DST], + info->rti_info[RTAX_NETMASK]) && + rop->priority < rtm->rtm_priority)) + continue; + switch (rtm->rtm_type) { case RTM_IFANNOUNCE: case RTM_DESYNC: @@ -767,7 +802,7 @@ fail: free(rtm, M_RTABLE, len); } if (m) - route_input(m, so, info.rti_info[RTAX_DST] ? + route_input(m, so, &info, info.rti_info[RTAX_DST] ? info.rti_info[RTAX_DST]->sa_family : AF_UNSPEC); return (error); @@ -1472,7 +1507,7 @@ rtm_miss(int type, struct rt_addrinfo *rtinfo, int flags, uint8_t prio, rtm->rtm_tableid = tableid; rtm->rtm_addrs = rtinfo->rti_addrs; rtm->rtm_index = ifidx; - route_input(m, NULL, sa ? sa->sa_family : AF_UNSPEC); + route_input(m, NULL, NULL, sa ? sa->sa_family : AF_UNSPEC); } /* @@ -1497,7 +1532,7 @@ rtm_ifchg(struct ifnet *ifp) ifm->ifm_xflags = ifp->if_xflags; if_getdata(ifp, &ifm->ifm_data); ifm->ifm_addrs = 0; - route_input(m, NULL, AF_UNSPEC); + route_input(m, NULL, NULL, AF_UNSPEC); } /* @@ -1533,7 +1568,7 @@ rtm_addr(struct rtentry *rt, int cmd, struct ifaddr *ifa) ifam->ifam_addrs = info.rti_addrs; ifam->ifam_tableid = ifp->if_rdomain; - route_input(m, NULL, + route_input(m, NULL, NULL, ifa->ifa_addr ? ifa->ifa_addr->sa_family : AF_UNSPEC); } @@ -1556,7 +1591,7 @@ rtm_ifannounce(struct ifnet *ifp, int what) ifan->ifan_index = ifp->if_index; strlcpy(ifan->ifan_name, ifp->if_xname, sizeof(ifan->ifan_name)); ifan->ifan_what = what; - route_input(m, NULL, AF_UNSPEC); + route_input(m, NULL, NULL, AF_UNSPEC); } #ifdef BFD @@ -1587,7 +1622,7 @@ rtm_bfd(struct bfd_config *bfd) bfd2sa(bfd->bc_rt, &sa_bfd); memcpy(&bfdm->bm_sa, &sa_bfd, sizeof(sa_bfd)); - route_input(m, NULL, info.rti_info[RTAX_DST]->sa_family); + route_input(m, NULL, NULL, info.rti_info[RTAX_DST]->sa_family); } #endif /* BFD */