[Linux-decnet-user] Some fixes backported to 2.4
Brought to you by:
chrissie_c,
ph3-der-loewe
|
From: Steven W. <st...@gw...> - 2003-04-17 22:30:10
|
Hi,
Here is a patch with some of the fixes from the 2.5 DECnet stack, but none
of the new features. There are other things which need fixing too, but this
will deal with several issues and is relatively straight forward so I'm
hoping to submit this sooner rather than later and follow up with further
patches as time permits,
Steve.
------------------------------------------------------------------------------
diff -Nru linux-2.4.21-pre7/include/net/dn_fib.h linux/include/net/dn_fib.h
--- linux-2.4.21-pre7/include/net/dn_fib.h Fri Dec 21 09:42:04 2001
+++ linux/include/net/dn_fib.h Thu Apr 17 15:16:03 2003
@@ -126,8 +126,6 @@
extern void dn_fib_cleanup(void);
extern int dn_fib_rt_message(struct sk_buff *skb);
-extern int dn_fib_ioctl(struct socket *sock, unsigned int cmd,
- unsigned long arg);
extern struct dn_fib_info *dn_fib_create_info(const struct rtmsg *r,
struct dn_kern_rta *rta,
const struct nlmsghdr *nlh, int *errp);
diff -Nru linux-2.4.21-pre7/include/net/dn_nsp.h linux/include/net/dn_nsp.h
--- linux-2.4.21-pre7/include/net/dn_nsp.h Mon Jan 22 13:32:10 2001
+++ linux/include/net/dn_nsp.h Thu Apr 17 14:11:11 2003
@@ -204,4 +204,6 @@
return atomic_read(&sk->rmem_alloc) > (sk->rcvbuf >> 1);
}
+#define DN_MAX_NSP_DATA_HEADER (11)
+
#endif /* _NET_DN_NSP_H */
diff -Nru linux-2.4.21-pre7/net/decnet/TODO linux/net/decnet/TODO
--- linux-2.4.21-pre7/net/decnet/TODO Mon Jan 22 13:32:10 2001
+++ linux/net/decnet/TODO Thu Apr 17 14:15:23 2003
@@ -1,17 +1,10 @@
Steve's quick list of things that need finishing off:
-[they are in no particular order and range from the trivial to the long winded]
+[they are in no particular order and range from the trivial to the long winded.
+I've also removed things which are 2.5 projects]
o Proper timeouts on each neighbour (in routing mode) rather than
just the 60 second On-Ethernet cache value.
- o Support for X.25 linklayer
-
- o Support for DDCMP link layer
-
- o The DDCMP device itself
-
- o PPP support (rfc1762)
-
o Lots of testing with real applications
o Verify errors etc. against POSIX 1003.1g (draft)
@@ -21,8 +14,6 @@
send/recvmsg() calls should simply be a vector of set/getsockopt()
calls]
- o check MSG_CTRUNC is set where it should be.
-
o Start to hack together user level software and add more DECnet support
in ifconfig for example.
@@ -30,28 +21,13 @@
o Test route lookup
- o Test /proc/net/decnet_route route listing works correctly (maybe I'll
- change the format of this file... atm its very similar to the IPv4 route
- file)
-
- o Find all the commonality between DECnet and IPv4 routing code and extract
- it into a small library of routines. [probably a project for 2.5.xx]
-
- o Test ip_gre tunneling works... it did the last time I tested it and it
- will have to if I'm to test routing properly.
-
o Hello messages should be generated for each primary address on each
interface.
- o Add the routing message grabbing netfilter module [written, tested,
- awaiting merge]
-
- o Add perfect socket hashing - an idea suggested by Paul Koning [part written,
- awaiting debugging and merge]
-
o Add session control message flow control
o Add NSP message flow control
- o DECnet sendpages() function
+ o Back port some of the fixes & features from DECnet in 2.5 as they become
+ stable and well tested
diff -Nru linux-2.4.21-pre7/net/decnet/af_decnet.c linux/net/decnet/af_decnet.c
--- linux-2.4.21-pre7/net/decnet/af_decnet.c Thu Nov 28 15:53:15 2002
+++ linux/net/decnet/af_decnet.c Thu Apr 17 14:16:58 2003
@@ -479,7 +479,7 @@
if (sock) {
sock->ops = &dn_proto_ops;
}
- sock_init_data(sock,sk);
+ sock_init_data(sock, sk);
scp = DN_SK(sk);
sk->backlog_rcv = dn_nsp_backlog_rcv;
@@ -1198,12 +1198,6 @@
release_sock(sk);
return val;
-#ifdef CONFIG_DECNET_ROUTER
- case SIOCADDRT:
- case SIOCDELRT:
- return dn_fib_ioctl(sock, cmd, arg);
-#endif /* CONFIG_DECNET_ROUTER */
-
case OSIOCSNETADDR:
if (!capable(CAP_NET_ADMIN)) {
err = -EPERM;
@@ -1222,10 +1216,6 @@
case OSIOCGNETADDR:
err = put_user(decnet_address, (unsigned short *)arg);
break;
- case SIOCGIFCONF:
- case SIOCGIFFLAGS:
- case SIOCGIFBRDADDR:
- return dev_ioctl(cmd,(void *)arg);
case TIOCOUTQ:
amount = sk->sndbuf - atomic_read(&sk->wmem_alloc);
@@ -1250,6 +1240,10 @@
release_sock(sk);
err = put_user(amount, (int *)arg);
break;
+
+ default:
+ err = dev_ioctl(cmd, (void *)arg);
+ break;
}
return err;
@@ -1897,7 +1891,7 @@
int len;
unsigned char fctype;
- if (flags & ~(MSG_TRYHARD|MSG_OOB|MSG_DONTWAIT|MSG_EOR))
+ if (flags & ~(MSG_TRYHARD|MSG_OOB|MSG_DONTWAIT|MSG_EOR|MSG_MORE))
return -EOPNOTSUPP;
if (addr_len && (addr_len != sizeof(struct sockaddr_dn)))
@@ -2216,10 +2210,8 @@
sendpage: sock_no_sendpage,
};
-#ifdef CONFIG_SYSCTL
void dn_register_sysctl(void);
void dn_unregister_sysctl(void);
-#endif
#ifdef MODULE
@@ -2269,9 +2261,7 @@
dn_fib_init();
#endif /* CONFIG_DECNET_ROUTER */
-#ifdef CONFIG_SYSCTL
dn_register_sysctl();
-#endif /* CONFIG_SYSCTL */
/*
* Prevent DECnet module unloading until its fixed properly.
@@ -2304,9 +2294,7 @@
sock_unregister(AF_DECnet);
dev_remove_pack(&dn_dix_packet_type);
-#ifdef CONFIG_SYSCTL
dn_unregister_sysctl();
-#endif /* CONFIG_SYSCTL */
unregister_netdevice_notifier(&dn_dev_notifier);
diff -Nru linux-2.4.21-pre7/net/decnet/dn_dev.c linux/net/decnet/dn_dev.c
--- linux-2.4.21-pre7/net/decnet/dn_dev.c Fri Dec 21 09:42:05 2001
+++ linux/net/decnet/dn_dev.c Thu Apr 17 14:19:30 2003
@@ -693,8 +693,6 @@
}
-#ifdef CONFIG_DECNET_ROUTER
-
#define DRDELAY (5 * HZ)
static int dn_am_i_a_router(struct dn_neigh *dn, struct dn_dev *dn_db)
@@ -800,12 +798,6 @@
else
dn_send_router_hello(dev);
}
-#else
-static void dn_send_brd_hello(struct net_device *dev)
-{
- dn_send_endnode_hello(dev);
-}
-#endif
#if 0
static void dn_send_ptp_hello(struct net_device *dev)
@@ -1034,19 +1026,22 @@
{
struct net_device *dev;
+ rtnl_lock();
for(dev = dev_base; dev; dev = dev->next)
dn_dev_down(dev);
-
+ rtnl_unlock();
}
void dn_dev_devices_on(void)
{
struct net_device *dev;
+ rtnl_lock();
for(dev = dev_base; dev; dev = dev->next) {
if (dev->flags & IFF_UP)
dn_dev_up(dev);
}
+ rtnl_unlock();
}
diff -Nru linux-2.4.21-pre7/net/decnet/dn_fib.c linux/net/decnet/dn_fib.c
--- linux-2.4.21-pre7/net/decnet/dn_fib.c Fri Dec 21 09:42:05 2001
+++ linux/net/decnet/dn_fib.c Thu Apr 17 15:21:37 2003
@@ -52,7 +52,7 @@
extern int dn_cache_dump(struct sk_buff *skb, struct netlink_callback *cb);
-
+static spinlock_t dn_fib_multipath_lock = SPIN_LOCK_UNLOCKED;
static struct dn_fib_info *dn_fib_info_list;
static rwlock_t dn_fib_info_lock = RW_LOCK_UNLOCKED;
int dn_fib_info_cnt;
@@ -297,6 +297,13 @@
nh->nh_weight = 1;
}
+ if (r->rtm_type == RTN_NAT) {
+ if (rta->rta_gw == NULL || nhs != 1 || rta->rta_oif)
+ goto err_inval;
+ memcpy(&fi->fib_nh->nh_gw, rta->rta_gw, 2);
+ goto link_it;
+ }
+
if (dn_fib_props[r->rtm_type].error) {
if (rta->rta_gw || rta->rta_oif || rta->rta_mp)
goto err_inval;
@@ -328,7 +335,7 @@
if (fi->fib_prefsrc) {
if (r->rtm_type != RTN_LOCAL || rta->rta_dst == NULL ||
memcmp(&fi->fib_prefsrc, rta->rta_dst, 2))
- if (dn_addr_type(fi->fib_prefsrc) != RTN_LOCAL)
+ if (dnet_addr_type(fi->fib_prefsrc) != RTN_LOCAL)
goto err_inval;
}
#endif
@@ -366,12 +373,53 @@
return NULL;
}
+int dn_fib_semantic_match(int type, struct dn_fib_info *fi, const struct dn_fib_key *key, struct dn_fib_res *res)
+{
+ int err = dn_fib_props[type].error;
+
+ if (err == 0) {
+ if (fi->fib_flags & RTNH_F_DEAD)
+ return 1;
+
+ res->fi = fi;
+
+ switch(type) {
+ case RTN_NAT:
+ DN_FIB_RES_RESET(*res);
+ atomic_inc(&fi->fib_clntref);
+ return 0;
+ case RTN_UNICAST:
+ case RTN_LOCAL:
+ for_nexthops(fi) {
+ if (nh->nh_flags & RTNH_F_DEAD)
+ continue;
+ if (!key->oif || key->oif == nh->nh_oif)
+ break;
+ }
+ if (nhsel < fi->fib_nhs) {
+ res->nh_sel = nhsel;
+ atomic_inc(&fi->fib_clntref);
+ return 0;
+ }
+ endfor_nexthops(fi);
+ res->fi = NULL;
+ return 1;
+ default:
+ if (net_ratelimit())
+ printk("DECnet: impossible routing event : dn_fib_semantic_match type=%d\n", type);
+ res->fi = NULL;
+ return -EINVAL;
+ }
+ }
+ return err;
+}
void dn_fib_select_multipath(const struct dn_fib_key *key, struct dn_fib_res *res)
{
struct dn_fib_info *fi = res->fi;
int w;
+ spin_lock_bh(&dn_fib_multipath_lock);
if (fi->fib_power <= 0) {
int power = 0;
change_nexthops(fi) {
@@ -381,6 +429,11 @@
}
} endfor_nexthops(fi);
fi->fib_power = power;
+ if (power < 0) {
+ spin_unlock_bh(&dn_fib_multipath_lock);
+ res->nh_sel = 0;
+ return;
+ }
}
w = jiffies % fi->fib_power;
@@ -391,12 +444,13 @@
nh->nh_power--;
fi->fib_power--;
res->nh_sel = nhsel;
+ spin_unlock_bh(&dn_fib_multipath_lock);
return;
}
}
} endfor_nexthops(fi);
-
- printk(KERN_DEBUG "DECnet: BUG! dn_fib_select_multipath\n");
+ res->nh_sel = 0;
+ spin_unlock_bh(&dn_fib_multipath_lock);
}
@@ -477,7 +531,7 @@
if (s_t == 0)
s_t = cb->args[0] = DN_MIN_TABLE;
- for(t = s_t; t < DN_NUM_TABLES; t++) {
+ for(t = s_t; t <= RT_TABLE_MAX; t++) {
if (t < s_t)
continue;
if (t > s_t)
@@ -520,9 +574,11 @@
dead++;
else if (nh->nh_dev == dev &&
nh->nh_scope != scope) {
+ spin_lock_bh(&dn_fib_multipath_lock);
nh->nh_flags |= RTNH_F_DEAD;
fi->fib_power -= nh->nh_power;
nh->nh_power = 0;
+ spin_unlock_bh(&dn_fib_multipath_lock);
dead++;
}
} endfor_nexthops(fi)
@@ -556,11 +612,13 @@
if (nh->nh_dev != dev || dev->dn_ptr == NULL)
continue;
alive++;
+ spin_lock_bh(&dn_fib_multipath_lock);
nh->nh_power = 0;
nh->nh_flags &= ~RTNH_F_DEAD;
+ spin_unlock_bh(&dn_fib_multipath_lock);
} endfor_nexthops(fi);
- if (alive == fi->fib_nhs) {
+ if (alive > 0) {
fi->fib_flags &= ~RTNH_F_DEAD;
ret++;
}
@@ -584,20 +642,6 @@
dn_rt_cache_flush(-1);
}
-int dn_fib_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
-{
-
- if (!capable(CAP_NET_ADMIN))
- return -EPERM;
-
- switch(cmd) {
- case SIOCADDRT:
- case SIOCDELRT:
- return 0;
- }
-
- return -EINVAL;
-}
#ifdef CONFIG_PROC_FS
@@ -620,7 +664,7 @@
}
- for(i = DN_MIN_TABLE; (i <= DN_NUM_TABLES) && (count > 0); i++) {
+ for(i = DN_MIN_TABLE; (i <= RT_TABLE_MAX) && (count > 0); i++) {
if ((tb = dn_fib_get_table(i, 0)) != NULL) {
int n = tb->get_info(tb, ptr, first, count);
count -= n;
diff -Nru linux-2.4.21-pre7/net/decnet/dn_neigh.c linux/net/decnet/dn_neigh.c
--- linux-2.4.21-pre7/net/decnet/dn_neigh.c Mon Jan 22 13:32:10 2001
+++ linux/net/decnet/dn_neigh.c Thu Apr 17 14:26:09 2003
@@ -464,7 +464,6 @@
}
-#ifdef CONFIG_DECNET_ROUTER
static char *dn_find_slot(char *base, int max, int priority)
{
int i;
@@ -523,8 +522,6 @@
return t;
}
-#endif /* CONFIG_DECNET_ROUTER */
-
#ifdef CONFIG_PROC_FS
diff -Nru linux-2.4.21-pre7/net/decnet/dn_nsp_in.c linux/net/decnet/dn_nsp_in.c
--- linux-2.4.21-pre7/net/decnet/dn_nsp_in.c Thu Apr 17 15:25:39 2003
+++ linux/net/decnet/dn_nsp_in.c Thu Apr 17 15:25:25 2003
@@ -433,7 +433,15 @@
sk->state_change(sk);
}
- dn_nsp_send_disc(sk, NSP_DISCCONF, NSP_REASON_DC, GFP_ATOMIC);
+ /*
+ * It appears that its possible for remote machines to send disc
+ * init messages with no port identifier if we are in the CI and
+ * possibly also the CD state. Obviously we shouldn't reply with
+ * a message if we don't know what the end point is.
+ */
+ if (scp->addrrem) {
+ dn_nsp_send_disc(sk, NSP_DISCCONF, NSP_REASON_DC, GFP_ATOMIC);
+ }
scp->persist_fxn = dn_destroy_timer;
scp->persist = dn_nsp_persist(sk);
diff -Nru linux-2.4.21-pre7/net/decnet/dn_nsp_out.c linux/net/decnet/dn_nsp_out.c
--- linux-2.4.21-pre7/net/decnet/dn_nsp_out.c Mon Jan 22 13:32:10 2001
+++ linux/net/decnet/dn_nsp_out.c Thu Apr 17 14:30:01 2003
@@ -369,8 +369,6 @@
if ((jiffies - scp->stamp) > t)
scp->snd_window = NSP_MIN_WINDOW;
- /* printk(KERN_DEBUG "Window: %lu\n", scp->snd_window); */
-
cb->xmit_count = 0;
if (oth)
diff -Nru linux-2.4.21-pre7/net/decnet/dn_route.c linux/net/decnet/dn_route.c
--- linux-2.4.21-pre7/net/decnet/dn_route.c Thu Nov 28 15:53:15 2002
+++ linux/net/decnet/dn_route.c Thu Apr 17 15:18:41 2003
@@ -65,8 +65,8 @@
#include <linux/netdevice.h>
#include <linux/inet.h>
#include <linux/route.h>
+#include <linux/in_route.h>
#include <net/sock.h>
-#include <linux/fcntl.h>
#include <linux/mm.h>
#include <linux/proc_fs.h>
#include <linux/init.h>
@@ -641,7 +641,9 @@
struct dn_skb_cb *cb = DN_SKB_CB(skb);
struct dst_entry *dst = skb->dst;
struct neighbour *neigh;
+#ifdef CONFIG_NETFILTER
struct net_device *dev = skb->dev;
+#endif
int err = -EINVAL;
if ((neigh = dst->neighbour) == NULL)
@@ -1035,20 +1037,24 @@
nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(*r));
r = NLMSG_DATA(nlh);
- nlh->nlmsg_flags = nowait ? NLM_F_MULTI : 0;
+ nlh->nlmsg_flags = (nowait && pid) ? NLM_F_MULTI : 0;
r->rtm_family = AF_DECnet;
r->rtm_dst_len = 16;
- r->rtm_src_len = 16;
+ r->rtm_src_len = 0;
r->rtm_tos = 0;
- r->rtm_table = 0;
+ r->rtm_table = DN_MIN_TABLE;
r->rtm_type = 0;
r->rtm_flags = 0;
r->rtm_scope = RT_SCOPE_UNIVERSE;
r->rtm_protocol = RTPROT_UNSPEC;
RTA_PUT(skb, RTA_DST, 2, &rt->rt_daddr);
- RTA_PUT(skb, RTA_SRC, 2, &rt->rt_saddr);
+ if (rt->rt_saddr) {
+ r->rtm_src_len = 16;
+ RTA_PUT(skb, RTA_SRC, 2, &rt->rt_saddr);
+ }
if (rt->u.dst.dev)
RTA_PUT(skb, RTA_OIF, sizeof(int), &rt->u.dst.dev->ifindex);
+ RTA_PUT(skb, RTA_PREFSRC, 2, &rt->rt_saddr);
if (rt->u.dst.window)
RTA_PUT(skb, RTAX_WINDOW, sizeof(unsigned), &rt->u.dst.window);
if (rt->u.dst.rtt)
@@ -1110,12 +1116,12 @@
local_bh_enable();
memset(cb, 0, sizeof(struct dn_skb_cb));
rt = (struct dn_route *)skb->dst;
+ if (!err && rt->u.dst.error)
+ err = rt->u.dst.error;
} else {
err = dn_route_output((struct dst_entry **)&rt, dst, src, 0);
}
- if (!err && rt->u.dst.error)
- err = rt->u.dst.error;
if (skb->dev)
dev_put(skb->dev);
skb->dev = NULL;
diff -Nru linux-2.4.21-pre7/net/decnet/dn_rules.c linux/net/decnet/dn_rules.c
--- linux-2.4.21-pre7/net/decnet/dn_rules.c Fri Dec 21 09:42:05 2001
+++ linux/net/decnet/dn_rules.c Thu Apr 17 15:22:08 2003
@@ -26,6 +26,7 @@
#include <linux/netdevice.h>
#include <linux/timer.h>
#include <linux/spinlock.h>
+#include <linux/in_route.h>
#include <asm/atomic.h>
#include <asm/uaccess.h>
#include <net/neighbour.h>
@@ -48,6 +49,7 @@
dn_address r_srcmask;
dn_address r_dst;
dn_address r_dstmask;
+ dn_address r_srcmap;
u8 r_flags;
#ifdef CONFIG_DECNET_ROUTE_FWMARK
u32 r_fwmark;
@@ -60,7 +62,7 @@
static struct dn_fib_rule default_rule = {
r_clntref: ATOMIC_INIT(2),
r_preference: 0x7fff,
- r_table: DN_DEFAULT_TABLE,
+ r_table: RT_TABLE_MAIN,
r_action: RTN_UNICAST
};
@@ -150,6 +152,8 @@
memcpy(&new_r->r_src, RTA_DATA(rta[RTA_SRC-1]), 2);
if (rta[RTA_DST-1])
memcpy(&new_r->r_dst, RTA_DATA(rta[RTA_DST-1]), 2);
+ if (rta[RTA_GATEWAY-1])
+ memcpy(&new_r->r_srcmap, RTA_DATA(rta[RTA_GATEWAY-1]), 2);
new_r->r_src_len = rtm->rtm_src_len;
new_r->r_dst_len = rtm->rtm_dst_len;
new_r->r_srcmask = dnet_make_mask(rtm->rtm_src_len);
@@ -218,6 +222,7 @@
switch(r->r_action) {
case RTN_UNICAST:
+ case RTN_NAT:
policy = r;
break;
case RTN_UNREACHABLE:
@@ -330,6 +335,8 @@
RTA_PUT(skb, RTA_IIF, IFNAMSIZ, &r->r_ifname);
if (r->r_preference)
RTA_PUT(skb, RTA_PRIORITY, 4, &r->r_preference);
+ if (r->r_srcmap)
+ RTA_PUT(skb, RTA_GATEWAY, 2, &r->r_srcmap);
nlh->nlmsg_len = skb->tail - b;
return skb->len;
diff -Nru linux-2.4.21-pre7/net/decnet/dn_table.c linux/net/decnet/dn_table.c
--- linux-2.4.21-pre7/net/decnet/dn_table.c Fri Dec 21 09:42:05 2001
+++ linux/net/decnet/dn_table.c Thu Apr 17 14:42:07 2003
@@ -45,7 +45,7 @@
u32 dz_hashmask;
#define DZ_HASHMASK(dz) ((dz)->dz_hashmask)
int dz_order;
- u32 dz_mask;
+ u16 dz_mask;
#define DZ_MASK(dz) ((dz)->dz_mask)
};
@@ -75,17 +75,16 @@
static rwlock_t dn_fib_tables_lock = RW_LOCK_UNLOCKED;
-static struct dn_fib_table *dn_fib_tables[DN_NUM_TABLES + 1];
+static struct dn_fib_table *dn_fib_tables[RT_TABLE_MAX + 1];
static kmem_cache_t *dn_hash_kmem;
static int dn_fib_hash_zombies;
static __inline__ dn_fib_idx_t dn_hash(dn_fib_key_t key, struct dn_zone *dz)
{
- u32 h = ntohs(key.datum)>>(16 - dz->dz_order);
+ u16 h = ntohs(key.datum)>>(16 - dz->dz_order);
h ^= (h >> 10);
h ^= (h >> 6);
- h ^= (h >> 3);
h &= DZ_HASHMASK(dz);
return *(dn_fib_idx_t *)&h;
}
@@ -118,8 +117,8 @@
}
static __inline__ void dn_rebuild_zone(struct dn_zone *dz,
- struct dn_fib_node **old_ht,
- int old_divisor)
+ struct dn_fib_node **old_ht,
+ int old_divisor)
{
int i;
struct dn_fib_node *f, **fp, *next;
@@ -709,10 +708,12 @@
dn_fib_key_t k = dz_key(key->dst, dz);
for(f = dz_chain(k, dz); f; f = f->fn_next) {
- if (!dn_key_leq(k, f->fn_key))
- break;
- else
- continue;
+ if (!dn_key_eq(k, f->fn_key)) {
+ if (!dn_key_leq(k, f->fn_key))
+ break;
+ else
+ continue;
+ }
f->fn_state |= DN_S_ACCESSED;
@@ -826,7 +827,7 @@
if (n < DN_MIN_TABLE)
return NULL;
- if (n > DN_NUM_TABLES)
+ if (n > RT_TABLE_MAX)
return NULL;
if (dn_fib_tables[n])
@@ -840,7 +841,7 @@
from interrupt\n");
return NULL;
}
- if ((t = kmalloc(sizeof(struct dn_fib_table), GFP_KERNEL)) == NULL)
+ if ((t = kmalloc(sizeof(struct dn_fib_table) + sizeof(struct dn_hash), GFP_KERNEL)) == NULL)
return NULL;
memset(t, 0, sizeof(struct dn_fib_table));
@@ -854,6 +855,7 @@
t->get_info = dn_fib_table_get_info;
#endif
t->dump = dn_fib_table_dump;
+ memset(t->data, 0, sizeof(struct dn_hash));
dn_fib_tables[n] = t;
return t;
|