diff options
Diffstat (limited to 'net/ipv4/ipmr.c')
| -rw-r--r-- | net/ipv4/ipmr.c | 41 |
1 files changed, 22 insertions, 19 deletions
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index c94bbc6f2ba3..8eec8f4a0536 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c | |||
| @@ -524,8 +524,8 @@ failure: | |||
| 524 | } | 524 | } |
| 525 | #endif | 525 | #endif |
| 526 | 526 | ||
| 527 | /* | 527 | /** |
| 528 | * Delete a VIF entry | 528 | * vif_delete - Delete a VIF entry |
| 529 | * @notify: Set to 1, if the caller is a notifier_call | 529 | * @notify: Set to 1, if the caller is a notifier_call |
| 530 | */ | 530 | */ |
| 531 | 531 | ||
| @@ -1795,9 +1795,12 @@ static struct mr_table *ipmr_rt_fib_lookup(struct net *net, struct sk_buff *skb) | |||
| 1795 | .daddr = iph->daddr, | 1795 | .daddr = iph->daddr, |
| 1796 | .saddr = iph->saddr, | 1796 | .saddr = iph->saddr, |
| 1797 | .flowi4_tos = RT_TOS(iph->tos), | 1797 | .flowi4_tos = RT_TOS(iph->tos), |
| 1798 | .flowi4_oif = rt->rt_oif, | 1798 | .flowi4_oif = (rt_is_output_route(rt) ? |
| 1799 | .flowi4_iif = rt->rt_iif, | 1799 | skb->dev->ifindex : 0), |
| 1800 | .flowi4_mark = rt->rt_mark, | 1800 | .flowi4_iif = (rt_is_output_route(rt) ? |
| 1801 | net->loopback_dev->ifindex : | ||
| 1802 | skb->dev->ifindex), | ||
| 1803 | .flowi4_mark = skb->mark, | ||
| 1801 | }; | 1804 | }; |
| 1802 | struct mr_table *mrt; | 1805 | struct mr_table *mrt; |
| 1803 | int err; | 1806 | int err; |
| @@ -2006,37 +2009,37 @@ static int __ipmr_fill_mroute(struct mr_table *mrt, struct sk_buff *skb, | |||
| 2006 | { | 2009 | { |
| 2007 | int ct; | 2010 | int ct; |
| 2008 | struct rtnexthop *nhp; | 2011 | struct rtnexthop *nhp; |
| 2009 | u8 *b = skb_tail_pointer(skb); | 2012 | struct nlattr *mp_attr; |
| 2010 | struct rtattr *mp_head; | ||
| 2011 | 2013 | ||
| 2012 | /* If cache is unresolved, don't try to parse IIF and OIF */ | 2014 | /* If cache is unresolved, don't try to parse IIF and OIF */ |
| 2013 | if (c->mfc_parent >= MAXVIFS) | 2015 | if (c->mfc_parent >= MAXVIFS) |
| 2014 | return -ENOENT; | 2016 | return -ENOENT; |
| 2015 | 2017 | ||
| 2016 | if (VIF_EXISTS(mrt, c->mfc_parent)) | 2018 | if (VIF_EXISTS(mrt, c->mfc_parent) && |
| 2017 | RTA_PUT(skb, RTA_IIF, 4, &mrt->vif_table[c->mfc_parent].dev->ifindex); | 2019 | nla_put_u32(skb, RTA_IIF, mrt->vif_table[c->mfc_parent].dev->ifindex) < 0) |
| 2020 | return -EMSGSIZE; | ||
| 2018 | 2021 | ||
| 2019 | mp_head = (struct rtattr *)skb_put(skb, RTA_LENGTH(0)); | 2022 | if (!(mp_attr = nla_nest_start(skb, RTA_MULTIPATH))) |
| 2023 | return -EMSGSIZE; | ||
| 2020 | 2024 | ||
| 2021 | for (ct = c->mfc_un.res.minvif; ct < c->mfc_un.res.maxvif; ct++) { | 2025 | for (ct = c->mfc_un.res.minvif; ct < c->mfc_un.res.maxvif; ct++) { |
| 2022 | if (VIF_EXISTS(mrt, ct) && c->mfc_un.res.ttls[ct] < 255) { | 2026 | if (VIF_EXISTS(mrt, ct) && c->mfc_un.res.ttls[ct] < 255) { |
| 2023 | if (skb_tailroom(skb) < RTA_ALIGN(RTA_ALIGN(sizeof(*nhp)) + 4)) | 2027 | if (!(nhp = nla_reserve_nohdr(skb, sizeof(*nhp)))) { |
| 2024 | goto rtattr_failure; | 2028 | nla_nest_cancel(skb, mp_attr); |
| 2025 | nhp = (struct rtnexthop *)skb_put(skb, RTA_ALIGN(sizeof(*nhp))); | 2029 | return -EMSGSIZE; |
| 2030 | } | ||
| 2031 | |||
| 2026 | nhp->rtnh_flags = 0; | 2032 | nhp->rtnh_flags = 0; |
| 2027 | nhp->rtnh_hops = c->mfc_un.res.ttls[ct]; | 2033 | nhp->rtnh_hops = c->mfc_un.res.ttls[ct]; |
| 2028 | nhp->rtnh_ifindex = mrt->vif_table[ct].dev->ifindex; | 2034 | nhp->rtnh_ifindex = mrt->vif_table[ct].dev->ifindex; |
| 2029 | nhp->rtnh_len = sizeof(*nhp); | 2035 | nhp->rtnh_len = sizeof(*nhp); |
| 2030 | } | 2036 | } |
| 2031 | } | 2037 | } |
| 2032 | mp_head->rta_type = RTA_MULTIPATH; | 2038 | |
| 2033 | mp_head->rta_len = skb_tail_pointer(skb) - (u8 *)mp_head; | 2039 | nla_nest_end(skb, mp_attr); |
| 2040 | |||
| 2034 | rtm->rtm_type = RTN_MULTICAST; | 2041 | rtm->rtm_type = RTN_MULTICAST; |
| 2035 | return 1; | 2042 | return 1; |
| 2036 | |||
| 2037 | rtattr_failure: | ||
| 2038 | nlmsg_trim(skb, b); | ||
| 2039 | return -EMSGSIZE; | ||
| 2040 | } | 2043 | } |
| 2041 | 2044 | ||
| 2042 | int ipmr_get_route(struct net *net, struct sk_buff *skb, | 2045 | int ipmr_get_route(struct net *net, struct sk_buff *skb, |
