diff options
Diffstat (limited to 'net/ipv6/route.c')
-rw-r--r-- | net/ipv6/route.c | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 7a014ca877ed..c52a7f49d096 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -5123,6 +5123,38 @@ errout: | |||
5123 | rtnl_set_sk_err(net, RTNLGRP_IPV6_ROUTE, err); | 5123 | rtnl_set_sk_err(net, RTNLGRP_IPV6_ROUTE, err); |
5124 | } | 5124 | } |
5125 | 5125 | ||
5126 | void fib6_rt_update(struct net *net, struct fib6_info *rt, | ||
5127 | struct nl_info *info) | ||
5128 | { | ||
5129 | u32 seq = info->nlh ? info->nlh->nlmsg_seq : 0; | ||
5130 | struct sk_buff *skb; | ||
5131 | int err = -ENOBUFS; | ||
5132 | |||
5133 | /* call_fib6_entry_notifiers will be removed when in-kernel notifier | ||
5134 | * is implemented and supported for nexthop objects | ||
5135 | */ | ||
5136 | call_fib6_entry_notifiers(net, FIB_EVENT_ENTRY_REPLACE, rt, NULL); | ||
5137 | |||
5138 | skb = nlmsg_new(rt6_nlmsg_size(rt), gfp_any()); | ||
5139 | if (!skb) | ||
5140 | goto errout; | ||
5141 | |||
5142 | err = rt6_fill_node(net, skb, rt, NULL, NULL, NULL, 0, | ||
5143 | RTM_NEWROUTE, info->portid, seq, NLM_F_REPLACE); | ||
5144 | if (err < 0) { | ||
5145 | /* -EMSGSIZE implies BUG in rt6_nlmsg_size() */ | ||
5146 | WARN_ON(err == -EMSGSIZE); | ||
5147 | kfree_skb(skb); | ||
5148 | goto errout; | ||
5149 | } | ||
5150 | rtnl_notify(skb, net, info->portid, RTNLGRP_IPV6_ROUTE, | ||
5151 | info->nlh, gfp_any()); | ||
5152 | return; | ||
5153 | errout: | ||
5154 | if (err < 0) | ||
5155 | rtnl_set_sk_err(net, RTNLGRP_IPV6_ROUTE, err); | ||
5156 | } | ||
5157 | |||
5126 | static int ip6_route_dev_notify(struct notifier_block *this, | 5158 | static int ip6_route_dev_notify(struct notifier_block *this, |
5127 | unsigned long event, void *ptr) | 5159 | unsigned long event, void *ptr) |
5128 | { | 5160 | { |