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 */
 

Reply via email to