static void mpls_ifdown(struct net_device *dev, int event)
{
	struct mpls_route __rcu **platform_label;
	struct net *net = dev_net(dev);
	u8 alive, deleted;
	unsigned index;

	platform_label = rtnl_dereference(net->mpls.platform_label);
	for (index = 0; index < net->mpls.platform_labels; index++) {
		struct mpls_route *rt = rtnl_dereference(platform_label[index]);

		if (!rt)
			continue;

		alive = 0;
		deleted = 0;
		change_nexthops(rt) {
			unsigned int nh_flags = nh->nh_flags;

			if (rtnl_dereference(nh->nh_dev) != dev)
				goto next;

			switch (event) {
			case NETDEV_DOWN:
			case NETDEV_UNREGISTER:
				nh_flags |= RTNH_F_DEAD;
				/* fall through */
			case NETDEV_CHANGE:
				nh_flags |= RTNH_F_LINKDOWN;
				break;
			}
			if (event == NETDEV_UNREGISTER)
				RCU_INIT_POINTER(nh->nh_dev, NULL);

			if (nh->nh_flags != nh_flags)
				WRITE_ONCE(nh->nh_flags, nh_flags);
next:
			if (!(nh_flags & (RTNH_F_DEAD | RTNH_F_LINKDOWN)))
				alive++;
			if (!rtnl_dereference(nh->nh_dev))
				deleted++;
		} endfor_nexthops(rt);

		WRITE_ONCE(rt->rt_nhn_alive, alive);

		/* if there are no more nexthops, delete the route */
		if (event == NETDEV_UNREGISTER && deleted == rt->rt_nhn)
			mpls_route_update(net, index, NULL, NULL);
	}
}
static void mpls_ifdown(struct net_device *dev, int event)
{
	struct mpls_route __rcu **platform_label;
	struct net *net = dev_net(dev);
	u8 alive, deleted;
	unsigned index;

	platform_label = rtnl_dereference(net->mpls.platform_label);
	for (index = 0; index < net->mpls.platform_labels; index++) {
		struct mpls_route *rt = rtnl_dereference(platform_label[index]);

		if (!rt)
			continue;

		alive = 0;
		deleted = 0;
		change_nexthops(rt) {
			unsigned int nh_flags = nh->nh_flags;

			if (rtnl_dereference(nh->nh_dev) != dev)
				goto next;

			switch (event) {
			case NETDEV_DOWN:
			case NETDEV_UNREGISTER:
				nh_flags |= RTNH_F_DEAD;
				 
			case NETDEV_CHANGE:
				nh_flags |= RTNH_F_LINKDOWN;
				break;
			}
			if (event == NETDEV_UNREGISTER)
				RCU_INIT_POINTER(nh->nh_dev, NULL);

			if (nh->nh_flags != nh_flags)
				WRITE_ONCE(nh->nh_flags, nh_flags);
next:
			if (!(nh_flags & (RTNH_F_DEAD | RTNH_F_LINKDOWN)))
				alive++;
			if (!rtnl_dereference(nh->nh_dev))
				deleted++;
		} endfor_nexthops(rt);

		WRITE_ONCE(rt->rt_nhn_alive, alive);

		 
		if (event == NETDEV_UNREGISTER && deleted == rt->rt_nhn)
			mpls_route_update(net, index, NULL, NULL);
	}
}