int dn_fib_rtm_delrule(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
{
struct rtattr **rta = arg;
struct rtmsg *rtm = NLMSG_DATA(nlh);
int dn_fib_rtm_delrule(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
{
struct rtattr **rta = arg;
struct rtmsg *rtm = NLMSG_DATA(nlh);
if ((!rta[RTA_SRC-1] || memcmp(RTA_DATA(rta[RTA_SRC-1]), &r->r_src, 2) == 0) &&
rtm->rtm_src_len == r->r_src_len &&
rtm->rtm_dst_len == r->r_dst_len &&
if ((!rta[RTA_SRC-1] || memcmp(RTA_DATA(rta[RTA_SRC-1]), &r->r_src, 2) == 0) &&
rtm->rtm_src_len == r->r_src_len &&
rtm->rtm_dst_len == r->r_dst_len &&
- struct dn_fib_rule *r, *new_r, *last = NULL;
- struct hlist_node *node = NULL;
+ struct dn_fib_rule *r, *new_r, **rp;
- if (r && r->r_hlist.next != NULL) {
- r = container_of(r->r_hlist.next, struct dn_fib_rule, r_hlist);
+ r = dn_fib_rules;
+ if (r && (r = r->r_next) != NULL) {
+ rp = &dn_fib_rules->r_next;
- if (last)
- hlist_add_after_rcu(&last->r_hlist, &new_r->r_hlist);
- else
- hlist_add_before_rcu(&new_r->r_hlist, &r->r_hlist);
+ new_r->r_next = r;
+ atomic_inc(&new_r->r_clntref);
+ write_lock_bh(&dn_fib_rules_lock);
+ *rp = new_r;
+ write_unlock_bh(&dn_fib_rules_lock);
- __le16 saddr = flp->fld_src;
- __le16 daddr = flp->fld_dst;
- struct hlist_node *node;
+ dn_address saddr = flp->fld_src;
+ dn_address daddr = flp->fld_dst;
- rcu_read_lock();
-
- hlist_for_each_entry_rcu(r, node, &dn_fib_rules, r_hlist) {
+ read_lock(&dn_fib_rules_lock);
+ for(r = dn_fib_rules; r; r = r->r_next) {
if (((saddr^r->r_src) & r->r_srcmask) ||
((daddr^r->r_dst) & r->r_dstmask) ||
#ifdef CONFIG_DECNET_ROUTE_FWMARK
if (((saddr^r->r_src) & r->r_srcmask) ||
((daddr^r->r_dst) & r->r_dstmask) ||
#ifdef CONFIG_DECNET_ROUTE_FWMARK
- hlist_for_each_entry(r, node, &dn_fib_rules, r_hlist) {
- if (r->r_ifindex == dev->ifindex)
+ for(r = dn_fib_rules; r; r = r->r_next) {
+ if (r->r_ifindex == dev->ifindex) {
+ write_lock_bh(&dn_fib_rules_lock);
- hlist_for_each_entry(r, node, &dn_fib_rules, r_hlist) {
- if (r->r_ifindex == -1 && strcmp(dev->name, r->r_ifname) == 0)
+ for(r = dn_fib_rules; r; r = r->r_next) {
+ if (r->r_ifindex == -1 && strcmp(dev->name, r->r_ifname) == 0) {
+ write_lock_bh(&dn_fib_rules_lock);
- rcu_read_lock();
- hlist_for_each_entry(r, node, &dn_fib_rules, r_hlist) {
+ read_lock(&dn_fib_rules_lock);
+ for(r = dn_fib_rules, idx = 0; r; r = r->r_next, idx++) {
if (dn_fib_fill_rule(skb, r, cb, NLM_F_MULTI) < 0)
break;
if (dn_fib_fill_rule(skb, r, cb, NLM_F_MULTI) < 0)
break;