Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 19a3b7ee authored by David Ahern's avatar David Ahern Committed by David S. Miller
Browse files

ipv6: export function to send route updates



Add fib6_rt_update to send RTM_NEWROUTE with NLM_F_REPLACE set. This
helper will be used by the nexthop code to notify userspace of routes
that are impacted when a nexthop config is updated via replace.

This notification is needed for legacy apps that do not understand
the new nexthop object. Apps that are nexthop aware can use the
RTA_NH_ID attribute in the route notification to just ignore it.

In the future this should be wrapped in a sysctl to allow OS'es that
are fully updated to avoid the notificaton storm.

Signed-off-by: default avatarDavid Ahern <dsahern@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent cdaa16a4
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -452,6 +452,12 @@ int fib6_nh_init(struct net *net, struct fib6_nh *fib6_nh,
		 struct netlink_ext_ack *extack);
void fib6_nh_release(struct fib6_nh *fib6_nh);

int call_fib6_entry_notifiers(struct net *net,
			      enum fib_event_type event_type,
			      struct fib6_info *rt,
			      struct netlink_ext_ack *extack);
void fib6_rt_update(struct net *net, struct fib6_info *rt,
		    struct nl_info *info);
void inet6_rt_notify(int event, struct fib6_info *rt, struct nl_info *info,
		     unsigned int flags);

+3 −0
Original line number Diff line number Diff line
@@ -47,6 +47,9 @@ struct ipv6_stub {
	void (*fib6_nh_release)(struct fib6_nh *fib6_nh);
	void (*fib6_update_sernum)(struct net *net, struct fib6_info *rt);
	int (*ip6_del_rt)(struct net *net, struct fib6_info *rt);
	void (*fib6_rt_update)(struct net *net, struct fib6_info *rt,
			       struct nl_info *info);

	void (*udpv6_encap_enable)(void);
	void (*ndisc_send_na)(struct net_device *dev, const struct in6_addr *daddr,
			      const struct in6_addr *solicited_addr,
+1 −0
Original line number Diff line number Diff line
@@ -927,6 +927,7 @@ static const struct ipv6_stub ipv6_stub_impl = {
	.fib6_nh_init	   = fib6_nh_init,
	.fib6_nh_release   = fib6_nh_release,
	.fib6_update_sernum = fib6_update_sernum_stub,
	.fib6_rt_update	   = fib6_rt_update,
	.ip6_del_rt	   = ip6_del_rt,
	.udpv6_encap_enable = udpv6_encap_enable,
	.ndisc_send_na = ndisc_send_na,
+4 −4
Original line number Diff line number Diff line
@@ -393,7 +393,7 @@ static int call_fib6_entry_notifier(struct notifier_block *nb, struct net *net,
	return call_fib6_notifier(nb, net, event_type, &info.info);
}

static int call_fib6_entry_notifiers(struct net *net,
int call_fib6_entry_notifiers(struct net *net,
			      enum fib_event_type event_type,
			      struct fib6_info *rt,
			      struct netlink_ext_ack *extack)
+32 −0
Original line number Diff line number Diff line
@@ -5123,6 +5123,38 @@ void inet6_rt_notify(int event, struct fib6_info *rt, struct nl_info *info,
		rtnl_set_sk_err(net, RTNLGRP_IPV6_ROUTE, err);
}

void fib6_rt_update(struct net *net, struct fib6_info *rt,
		    struct nl_info *info)
{
	u32 seq = info->nlh ? info->nlh->nlmsg_seq : 0;
	struct sk_buff *skb;
	int err = -ENOBUFS;

	/* call_fib6_entry_notifiers will be removed when in-kernel notifier
	 * is implemented and supported for nexthop objects
	 */
	call_fib6_entry_notifiers(net, FIB_EVENT_ENTRY_REPLACE, rt, NULL);

	skb = nlmsg_new(rt6_nlmsg_size(rt), gfp_any());
	if (!skb)
		goto errout;

	err = rt6_fill_node(net, skb, rt, NULL, NULL, NULL, 0,
			    RTM_NEWROUTE, info->portid, seq, NLM_F_REPLACE);
	if (err < 0) {
		/* -EMSGSIZE implies BUG in rt6_nlmsg_size() */
		WARN_ON(err == -EMSGSIZE);
		kfree_skb(skb);
		goto errout;
	}
	rtnl_notify(skb, net, info->portid, RTNLGRP_IPV6_ROUTE,
		    info->nlh, gfp_any());
	return;
errout:
	if (err < 0)
		rtnl_set_sk_err(net, RTNLGRP_IPV6_ROUTE, err);
}

static int ip6_route_dev_notify(struct notifier_block *this,
				unsigned long event, void *ptr)
{