diff options
Diffstat (limited to 'net/decnet/dn_table.c')
-rw-r--r-- | net/decnet/dn_table.c | 42 |
1 files changed, 23 insertions, 19 deletions
diff --git a/net/decnet/dn_table.c b/net/decnet/dn_table.c index 6c2445bcaba1..fc42a0afd306 100644 --- a/net/decnet/dn_table.c +++ b/net/decnet/dn_table.c | |||
@@ -224,26 +224,27 @@ static struct dn_zone *dn_new_zone(struct dn_hash *table, int z) | |||
224 | } | 224 | } |
225 | 225 | ||
226 | 226 | ||
227 | static int dn_fib_nh_match(struct rtmsg *r, struct nlmsghdr *nlh, struct dn_kern_rta *rta, struct dn_fib_info *fi) | 227 | static int dn_fib_nh_match(struct rtmsg *r, struct nlmsghdr *nlh, struct nlattr *attrs[], struct dn_fib_info *fi) |
228 | { | 228 | { |
229 | struct rtnexthop *nhp; | 229 | struct rtnexthop *nhp; |
230 | int nhlen; | 230 | int nhlen; |
231 | 231 | ||
232 | if (rta->rta_priority && *rta->rta_priority != fi->fib_priority) | 232 | if (attrs[RTA_PRIORITY] && |
233 | nla_get_u32(attrs[RTA_PRIORITY]) != fi->fib_priority) | ||
233 | return 1; | 234 | return 1; |
234 | 235 | ||
235 | if (rta->rta_oif || rta->rta_gw) { | 236 | if (attrs[RTA_OIF] || attrs[RTA_GATEWAY]) { |
236 | if ((!rta->rta_oif || *rta->rta_oif == fi->fib_nh->nh_oif) && | 237 | if ((!attrs[RTA_OIF] || nla_get_u32(attrs[RTA_OIF]) == fi->fib_nh->nh_oif) && |
237 | (!rta->rta_gw || memcmp(rta->rta_gw, &fi->fib_nh->nh_gw, 2) == 0)) | 238 | (!attrs[RTA_GATEWAY] || nla_get_le16(attrs[RTA_GATEWAY]) != fi->fib_nh->nh_gw)) |
238 | return 0; | 239 | return 0; |
239 | return 1; | 240 | return 1; |
240 | } | 241 | } |
241 | 242 | ||
242 | if (rta->rta_mp == NULL) | 243 | if (!attrs[RTA_MULTIPATH]) |
243 | return 0; | 244 | return 0; |
244 | 245 | ||
245 | nhp = RTA_DATA(rta->rta_mp); | 246 | nhp = nla_data(attrs[RTA_MULTIPATH]); |
246 | nhlen = RTA_PAYLOAD(rta->rta_mp); | 247 | nhlen = nla_len(attrs[RTA_MULTIPATH]); |
247 | 248 | ||
248 | for_nexthops(fi) { | 249 | for_nexthops(fi) { |
249 | int attrlen = nhlen - sizeof(struct rtnexthop); | 250 | int attrlen = nhlen - sizeof(struct rtnexthop); |
@@ -254,7 +255,10 @@ static int dn_fib_nh_match(struct rtmsg *r, struct nlmsghdr *nlh, struct dn_kern | |||
254 | if (nhp->rtnh_ifindex && nhp->rtnh_ifindex != nh->nh_oif) | 255 | if (nhp->rtnh_ifindex && nhp->rtnh_ifindex != nh->nh_oif) |
255 | return 1; | 256 | return 1; |
256 | if (attrlen) { | 257 | if (attrlen) { |
257 | gw = dn_fib_get_attr16(RTNH_DATA(nhp), attrlen, RTA_GATEWAY); | 258 | struct nlattr *gw_attr; |
259 | |||
260 | gw_attr = nla_find((struct nlattr *) (nhp + 1), attrlen, RTA_GATEWAY); | ||
261 | gw = gw_attr ? nla_get_le16(gw_attr) : 0; | ||
258 | 262 | ||
259 | if (gw && gw != nh->nh_gw) | 263 | if (gw && gw != nh->nh_gw) |
260 | return 1; | 264 | return 1; |
@@ -517,7 +521,8 @@ out: | |||
517 | return skb->len; | 521 | return skb->len; |
518 | } | 522 | } |
519 | 523 | ||
520 | static int dn_fib_table_insert(struct dn_fib_table *tb, struct rtmsg *r, struct dn_kern_rta *rta, struct nlmsghdr *n, struct netlink_skb_parms *req) | 524 | static int dn_fib_table_insert(struct dn_fib_table *tb, struct rtmsg *r, struct nlattr *attrs[], |
525 | struct nlmsghdr *n, struct netlink_skb_parms *req) | ||
521 | { | 526 | { |
522 | struct dn_hash *table = (struct dn_hash *)tb->data; | 527 | struct dn_hash *table = (struct dn_hash *)tb->data; |
523 | struct dn_fib_node *new_f, *f, **fp, **del_fp; | 528 | struct dn_fib_node *new_f, *f, **fp, **del_fp; |
@@ -536,15 +541,14 @@ static int dn_fib_table_insert(struct dn_fib_table *tb, struct rtmsg *r, struct | |||
536 | return -ENOBUFS; | 541 | return -ENOBUFS; |
537 | 542 | ||
538 | dz_key_0(key); | 543 | dz_key_0(key); |
539 | if (rta->rta_dst) { | 544 | if (attrs[RTA_DST]) { |
540 | __le16 dst; | 545 | __le16 dst = nla_get_le16(attrs[RTA_DST]); |
541 | memcpy(&dst, rta->rta_dst, 2); | ||
542 | if (dst & ~DZ_MASK(dz)) | 546 | if (dst & ~DZ_MASK(dz)) |
543 | return -EINVAL; | 547 | return -EINVAL; |
544 | key = dz_key(dst, dz); | 548 | key = dz_key(dst, dz); |
545 | } | 549 | } |
546 | 550 | ||
547 | if ((fi = dn_fib_create_info(r, rta, n, &err)) == NULL) | 551 | if ((fi = dn_fib_create_info(r, attrs, n, &err)) == NULL) |
548 | return err; | 552 | return err; |
549 | 553 | ||
550 | if (dz->dz_nent > (dz->dz_divisor << 2) && | 554 | if (dz->dz_nent > (dz->dz_divisor << 2) && |
@@ -654,7 +658,8 @@ out: | |||
654 | } | 658 | } |
655 | 659 | ||
656 | 660 | ||
657 | static int dn_fib_table_delete(struct dn_fib_table *tb, struct rtmsg *r, struct dn_kern_rta *rta, struct nlmsghdr *n, struct netlink_skb_parms *req) | 661 | static int dn_fib_table_delete(struct dn_fib_table *tb, struct rtmsg *r, struct nlattr *attrs[], |
662 | struct nlmsghdr *n, struct netlink_skb_parms *req) | ||
658 | { | 663 | { |
659 | struct dn_hash *table = (struct dn_hash*)tb->data; | 664 | struct dn_hash *table = (struct dn_hash*)tb->data; |
660 | struct dn_fib_node **fp, **del_fp, *f; | 665 | struct dn_fib_node **fp, **del_fp, *f; |
@@ -671,9 +676,8 @@ static int dn_fib_table_delete(struct dn_fib_table *tb, struct rtmsg *r, struct | |||
671 | return -ESRCH; | 676 | return -ESRCH; |
672 | 677 | ||
673 | dz_key_0(key); | 678 | dz_key_0(key); |
674 | if (rta->rta_dst) { | 679 | if (attrs[RTA_DST]) { |
675 | __le16 dst; | 680 | __le16 dst = nla_get_le16(attrs[RTA_DST]); |
676 | memcpy(&dst, rta->rta_dst, 2); | ||
677 | if (dst & ~DZ_MASK(dz)) | 681 | if (dst & ~DZ_MASK(dz)) |
678 | return -EINVAL; | 682 | return -EINVAL; |
679 | key = dz_key(dst, dz); | 683 | key = dz_key(dst, dz); |
@@ -703,7 +707,7 @@ static int dn_fib_table_delete(struct dn_fib_table *tb, struct rtmsg *r, struct | |||
703 | (r->rtm_scope == RT_SCOPE_NOWHERE || f->fn_scope == r->rtm_scope) && | 707 | (r->rtm_scope == RT_SCOPE_NOWHERE || f->fn_scope == r->rtm_scope) && |
704 | (!r->rtm_protocol || | 708 | (!r->rtm_protocol || |
705 | fi->fib_protocol == r->rtm_protocol) && | 709 | fi->fib_protocol == r->rtm_protocol) && |
706 | dn_fib_nh_match(r, n, rta, fi) == 0) | 710 | dn_fib_nh_match(r, n, attrs, fi) == 0) |
707 | del_fp = fp; | 711 | del_fp = fp; |
708 | } | 712 | } |
709 | 713 | ||