Hi I came across this old PR. It appears that it's not fixed in -current.

I attempted to port the diff to our FreeBSD 9.1 release machines which
have IPv6 connectivity and are affected by RA flooding.

I can report that it mitigates RA_flooding.

Feedback welcomed. I'd be happy to polish it so that it can
make it to 9.2 and 10.0 :-)

I broke down the diffs into separate ones.


--- in6.c.orig  2013-06-30 23:07:46.000000000 +0400
+++ in6.c       2013-07-01 19:20:15.000000000 +0400
@@ -2694,6 +2694,8 @@ in6_domifattach(struct ifnet *ifp)
        ext->nd_ifinfo = nd6_ifattach(ifp);
        ext->scope6_id = scope6_ifattach(ifp);
        ext->lltable = lltable_init(ifp, AF_INET6);
+       ext->nprefixes = 0;
+       ext->ndefrouters = 0;
        if (ext->lltable != NULL) {
                ext->lltable->llt_free = in6_lltable_free;
                ext->lltable->llt_prefix_free = in6_lltable_prefix_free;

--- in6_proto.c.orig    2013-06-30 23:07:58.000000000 +0400
+++ in6_proto.c 2013-07-01 21:05:08.000000000 +0400
@@ -413,7 +413,8 @@ VNET_DEFINE(int, ip6_rr_prune) = 5; /* r
                                         * walk list every 5 sec. */
 VNET_DEFINE(int, ip6_mcast_pmtu) = 0;  /* enable pMTU discovery for multicast? 
*/
 VNET_DEFINE(int, ip6_v6only) = 1;
-
+VNET_DEFINE(int, ip6_maxifprefixes) = 16;
+VNET_DEFINE(int, ip6_maxifdefrouters) = 16;
 VNET_DEFINE(int, ip6_keepfaith) = 0;
 VNET_DEFINE(time_t, ip6_log_time) = (time_t)0L;
 #ifdef IPSTEALTH
@@ -524,6 +525,10 @@ SYSCTL_VNET_STRUCT(_net_inet6_ip6, IPV6C
        &VNET_NAME(ip6stat), ip6stat, "");
 SYSCTL_VNET_INT(_net_inet6_ip6, IPV6CTL_MAXFRAGPACKETS, maxfragpackets,
        CTLFLAG_RW, &VNET_NAME(ip6_maxfragpackets), 0, "");
+SYSCTL_VNET_INT(_net_inet6_ip6, IPV6CTL_MAXIFPREFIXES, maxifprefixes,
+        CTLFLAG_RW, &VNET_NAME(ip6_maxifprefixes), 0, "");
+SYSCTL_VNET_INT(_net_inet6_ip6, IPV6CTL_MAXIFDEFROUTERS, maxifdefrouters,
+        CTLFLAG_RW, &VNET_NAME(ip6_maxifdefrouters), 0, "");
 SYSCTL_VNET_INT(_net_inet6_ip6, IPV6CTL_ACCEPT_RTADV, accept_rtadv,
        CTLFLAG_RW, &VNET_NAME(ip6_accept_rtadv), 0,
        "Default value of per-interface flag for accepting ICMPv6 Router"


--- in6_var.h.orig      2013-06-30 23:08:28.000000000 +0400
+++ in6_var.h   2013-07-01 22:38:03.000000000 +0400
@@ -104,6 +104,8 @@ struct in6_ifextra {
        struct scope6_id *scope6_id;
        struct lltable *lltable;
        struct mld_ifinfo *mld_ifinfo;
+       int nprefixes;
+       int ndefrouters;
 };
 
 #define        LLTABLE6(ifp)   (((struct in6_ifextra 
*)(ifp)->if_afdata[AF_INET6])->lltable)

--- ip6_var.h.orig      2013-06-30 23:09:22.000000000 +0400
+++ ip6_var.h   2013-07-01 20:28:30.000000000 +0400
@@ -315,6 +315,8 @@ VNET_DECLARE(int, ip6_maxfragpackets);      /
                                         * queue */
 VNET_DECLARE(int, ip6_maxfrags);       /* Maximum fragments in reassembly
                                         * queue */
+VNET_DECLARE(int, ip6_maxifprefixes);
+VNET_DECLARE(int, ip6_maxifdefrouters);
 VNET_DECLARE(int, ip6_accept_rtadv);   /* Acts as a host not a router */
 VNET_DECLARE(int, ip6_no_radr);                /* No defroute from RA */
 VNET_DECLARE(int, ip6_norbit_raif);    /* Disable R-bit in NA on RA

--- nd6.h.orig  2013-06-30 23:09:42.000000000 +0400
+++ nd6.h       2013-07-01 22:16:09.000000000 +0400
@@ -277,6 +277,7 @@ struct nd_prefix {
        u_char  ndpr_plen;
        int     ndpr_refcnt;    /* reference couter from addresses */
 };
+#define ndpr_next              ndpr_entry.le_next
 
 #define ndpr_raf               ndpr_flags
 #define ndpr_raf_onlink                ndpr_flags.onlink

--- nd6_rtr.c.orig      2013-06-30 23:10:24.000000000 +0400
+++ nd6_rtr.c   2013-07-01 22:40:29.000000000 +0400
@@ -83,6 +83,7 @@ static void nd6_rtmsg(int, struct rtentr
 static int in6_init_prefix_ltimes(struct nd_prefix *);
 static void in6_init_address_ltimes __P((struct nd_prefix *,
        struct in6_addrlifetime *));
+static void purge_detached(struct ifnet *);
 
 static int nd6_prefix_onlink(struct nd_prefix *);
 static int nd6_prefix_offlink(struct nd_prefix *);
@@ -565,6 +566,7 @@ defrtrlist_del(struct nd_defrouter *dr)
 {
        struct nd_defrouter *deldr = NULL;
        struct nd_prefix *pr;
+       struct in6_ifextra *ext = dr->ifp->if_afdata[AF_INET6];
 
        /*
         * Flush all the routing table entries that use the router
@@ -597,6 +599,12 @@ defrtrlist_del(struct nd_defrouter *dr)
        if (deldr)
                defrouter_select();
 
+       ext->ndefrouters--;
+       if (ext->ndefrouters < 0) {
+               log(LOG_WARNING, "defrtrlist_del: negative count on %s\n",
+                   dr->ifp->if_xname);
+       }
+
        free(dr, M_IP6NDP);
 }
 
@@ -734,6 +742,7 @@ static struct nd_defrouter *
 defrtrlist_update(struct nd_defrouter *new)
 {
        struct nd_defrouter *dr, *n;
+       struct in6_ifextra *ext = new->ifp->if_afdata[AF_INET6];
        int s = splnet();
 
        if ((dr = defrouter_lookup(&new->rtaddr, new->ifp)) != NULL) {
@@ -775,6 +784,12 @@ defrtrlist_update(struct nd_defrouter *n
                splx(s);
                return (dr);
        }
+       /*struct in6_ifextra *ext = new->ifp->if_afdata[AF_INET6];*/
+       if (ip6_maxifdefrouters >= 0 &&
+           ext->ndefrouters >= ip6_maxifdefrouters) {
+               splx(s);
+               return (NULL);
+       }
 
        /* entry does not exist */
        if (new->rtlifetime == 0) {
@@ -810,6 +825,8 @@ insert:
 
        defrouter_select();
 
_______________________________________________
freebsd-net@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-net
To unsubscribe, send any mail to "freebsd-net-unsubscr...@freebsd.org"

Reply via email to