Author: melifaro
Date: Sun Jan 10 06:43:43 2016
New Revision: 293626
URL: https://svnweb.freebsd.org/changeset/base/293626

Log:
  Make ipfw addr:kfib lookup algo use new routing KPI.

Modified:
  head/sys/netpfil/ipfw/ip_fw_table_algo.c

Modified: head/sys/netpfil/ipfw/ip_fw_table_algo.c
==============================================================================
--- head/sys/netpfil/ipfw/ip_fw_table_algo.c    Sun Jan 10 00:28:44 2016        
(r293625)
+++ head/sys/netpfil/ipfw/ip_fw_table_algo.c    Sun Jan 10 06:43:43 2016        
(r293626)
@@ -53,8 +53,10 @@ __FBSDID("$FreeBSD$");
 #include <net/route.h>
 
 #include <netinet/in.h>
+#include <netinet/in_fib.h>
 #include <netinet/ip_var.h>    /* struct ipfw_rule_ref */
 #include <netinet/ip_fw.h>
+#include <netinet6/in6_fib.h>
 
 #include <netpfil/ipfw/ip_fw_private.h>
 #include <netpfil/ipfw/ip_fw_table.h>
@@ -3778,7 +3780,6 @@ struct table_algo flow_hash = {
  *
  */
 
-static struct rtentry *lookup_kfib(void *key, int keylen, int fib);
 static int ta_lookup_kfib(struct table_info *ti, void *key, uint32_t keylen,
     uint32_t *val);
 static int kfib_parse_opts(int *pfib, char *data);
@@ -3792,46 +3793,44 @@ static void ta_dump_kfib_tinfo(void *ta_
 static int contigmask(uint8_t *p, int len);
 static int ta_dump_kfib_tentry(void *ta_state, struct table_info *ti, void *e,
     ipfw_obj_tentry *tent);
+static int ta_dump_kfib_tentry_int(struct sockaddr *paddr,
+    struct sockaddr *pmask, ipfw_obj_tentry *tent);
 static int ta_find_kfib_tentry(void *ta_state, struct table_info *ti,
     ipfw_obj_tentry *tent);
 static void ta_foreach_kfib(void *ta_state, struct table_info *ti,
     ta_foreach_f *f, void *arg);
 
-static struct rtentry *
-lookup_kfib(void *key, int keylen, int fib)
-{
-       struct sockaddr *s;
-
-       if (keylen == 4) {
-               struct sockaddr_in sin;
-               bzero(&sin, sizeof(sin));
-               sin.sin_len = sizeof(struct sockaddr_in);
-               sin.sin_family = AF_INET;
-               sin.sin_addr.s_addr = *(in_addr_t *)key;
-               s = (struct sockaddr *)&sin;
-       } else {
-               struct sockaddr_in6 sin6;
-               bzero(&sin6, sizeof(sin6));
-               sin6.sin6_len = sizeof(struct sockaddr_in6);
-               sin6.sin6_family = AF_INET6;
-               sin6.sin6_addr = *(struct in6_addr *)key;
-               s = (struct sockaddr *)&sin6;
-       }
-
-       return (rtalloc1_fib(s, 0, 0, fib));
-}
 
 static int
 ta_lookup_kfib(struct table_info *ti, void *key, uint32_t keylen,
     uint32_t *val)
 {
-       struct rtentry *rte;
+#ifdef INET
+       struct nhop4_basic nh4;
+       struct in_addr in;
+#endif
+#ifdef INET6
+       struct nhop6_basic nh6;
+#endif
+       int error;
 
-       if ((rte = lookup_kfib(key, keylen, ti->data)) == NULL)
+#ifdef INET
+       if (keylen == 4) {
+               in.s_addr = *(in_addr_t *)key;
+               error = fib4_lookup_nh_basic(ti->data,
+                   in, 0, 0, &nh4);
+       }
+#endif
+#ifdef INET6
+       if (keylen == 6)
+               error = fib6_lookup_nh_basic(ti->data,
+                   (struct in6_addr *)key, 0, 0, 0, &nh6);
+#endif
+
+       if (error != 0)
                return (0);
 
        *val = 0;
-       RTFREE_LOCKED(rte);
 
        return (1);
 }
@@ -3940,6 +3939,16 @@ ta_dump_kfib_tentry(void *ta_state, stru
     ipfw_obj_tentry *tent)
 {
        struct rtentry *rte;
+
+       rte = (struct rtentry *)e;
+
+       return ta_dump_kfib_tentry_int(rt_key(rte), rt_mask(rte), tent);
+}
+
+static int
+ta_dump_kfib_tentry_int(struct sockaddr *paddr, struct sockaddr *pmask,
+    ipfw_obj_tentry *tent)
+{
 #ifdef INET
        struct sockaddr_in *addr, *mask;
 #endif
@@ -3948,14 +3957,13 @@ ta_dump_kfib_tentry(void *ta_state, stru
 #endif
        int len;
 
-       rte = (struct rtentry *)e;
-       addr = (struct sockaddr_in *)rt_key(rte);
-       mask = (struct sockaddr_in *)rt_mask(rte);
        len = 0;
 
        /* Guess IPv4/IPv6 radix by sockaddr family */
 #ifdef INET
-       if (addr->sin_family == AF_INET) {
+       if (paddr->sa_family == AF_INET) {
+               addr = (struct sockaddr_in *)paddr;
+               mask = (struct sockaddr_in *)pmask;
                tent->k.addr.s_addr = addr->sin_addr.s_addr;
                len = 32;
                if (mask != NULL)
@@ -3968,9 +3976,9 @@ ta_dump_kfib_tentry(void *ta_state, stru
        }
 #endif
 #ifdef INET6
-       if (addr->sin_family == AF_INET6) {
-               addr6 = (struct sockaddr_in6 *)addr;
-               mask6 = (struct sockaddr_in6 *)mask;
+       if (paddr->sa_family == AF_INET6) {
+               addr6 = (struct sockaddr_in6 *)paddr;
+               mask6 = (struct sockaddr_in6 *)pmask;
                memcpy(&tent->k, &addr6->sin6_addr, sizeof(struct in6_addr));
                len = 128;
                if (mask6 != NULL)
@@ -3990,28 +3998,43 @@ static int
 ta_find_kfib_tentry(void *ta_state, struct table_info *ti,
     ipfw_obj_tentry *tent)
 {
-       struct rtentry *rte;
-       void *key;
-       int keylen;
+       struct rt_addrinfo info;
+       struct sockaddr_in6 key6, dst6, mask6;
+       struct sockaddr *dst, *key, *mask;
+
+       /* Prepare sockaddr for prefix/mask and info */
+       bzero(&dst6, sizeof(dst6));
+       dst6.sin6_len = sizeof(dst6);
+       dst = (struct sockaddr *)&dst6;
+       bzero(&mask6, sizeof(mask6));
+       mask6.sin6_len = sizeof(mask6);
+       mask = (struct sockaddr *)&mask6;
+
+       bzero(&info, sizeof(info));
+       info.rti_info[RTAX_DST] = dst;
+       info.rti_info[RTAX_NETMASK] = mask;
+
+       /* Prepare the lookup key */
+       bzero(&key6, sizeof(key6));
+       key6.sin6_family = tent->subtype;
+       key = (struct sockaddr *)&key6;
 
        if (tent->subtype == AF_INET) {
-               key = &tent->k.addr;
-               keylen = sizeof(struct in_addr);
+               ((struct sockaddr_in *)&key6)->sin_addr = tent->k.addr;
+               key6.sin6_len = sizeof(struct sockaddr_in);
        } else {
-               key = &tent->k.addr6;
-               keylen = sizeof(struct in6_addr);
+               key6.sin6_addr = tent->k.addr6;
+               key6.sin6_len = sizeof(struct sockaddr_in6);
        }
 
-       if ((rte = lookup_kfib(key, keylen, ti->data)) == NULL)
-               return (0);
+       if (rib_lookup_info(ti->data, key, 0, 0, &info) != 0)
+               return (ENOENT);
+       if ((info.rti_addrs & RTA_NETMASK) == 0)
+               mask = NULL;
 
-       if (rte != NULL) {
-               ta_dump_kfib_tentry(ta_state, ti, rte, tent);
-               RTFREE_LOCKED(rte);
-               return (0);
-       }
+       ta_dump_kfib_tentry_int(dst, mask, tent);
 
-       return (ENOENT);
+       return (0);
 }
 
 static void
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to