Lines Matching full:rt

74 static void rtmsg_lfib(int event, u32 label, struct mpls_route *rt,
103 static u8 *__mpls_nh_via(struct mpls_route *rt, struct mpls_nh *nh)
105 return (u8 *)nh + rt->rt_via_offset;
108 static const u8 *mpls_nh_via(const struct mpls_route *rt,
111 return __mpls_nh_via((struct mpls_route *)rt, (struct mpls_nh *)nh);
165 static u32 mpls_multipath_hash(struct mpls_route *rt, struct sk_buff *skb)
232 static struct mpls_nh *mpls_get_nexthop(struct mpls_route *rt, u8 index)
234 return (struct mpls_nh *)((u8 *)rt->rt_nh + index * rt->rt_nh_size);
237 /* number of alive nexthops (rt->rt_nhn_alive) and the flags for
242 static const struct mpls_nh *mpls_select_multipath(struct mpls_route *rt,
253 if (rt->rt_nhn == 1)
254 return rt->rt_nh;
256 alive = READ_ONCE(rt->rt_nhn_alive);
260 hash = mpls_multipath_hash(rt, skb);
262 if (alive == rt->rt_nhn)
264 for_nexthops(rt) {
272 } endfor_nexthops(rt);
275 return mpls_get_nexthop(rt, nh_index);
278 static bool mpls_egress(struct net *net, struct mpls_route *rt,
297 payload_type = rt->rt_payload_type;
311 if (rt->rt_ttl_propagate == MPLS_TTL_PROP_ENABLED ||
312 (rt->rt_ttl_propagate == MPLS_TTL_PROP_DEFAULT &&
333 if (rt->rt_ttl_propagate == MPLS_TTL_PROP_ENABLED ||
334 (rt->rt_ttl_propagate == MPLS_TTL_PROP_DEFAULT &&
356 struct mpls_route *rt;
395 rt = mpls_route_input_rcu(net, dec.label);
396 if (!rt) {
401 nh = mpls_select_multipath(rt, skb);
445 if (!mpls_egress(net, rt, skb, dec))
470 mpls_nh_via(rt, nh), skb);
522 struct mpls_route *rt;
525 size = sizeof(*rt) + num_nh * nh_size;
529 rt = kzalloc(size, GFP_KERNEL);
530 if (!rt)
533 rt->rt_nhn = num_nh;
534 rt->rt_nhn_alive = num_nh;
535 rt->rt_nh_size = nh_size;
536 rt->rt_via_offset = MPLS_NH_VIA_OFF(max_labels);
538 return rt;
543 struct mpls_route *rt;
545 rt = container_of(head, struct mpls_route, rt_rcu);
547 change_nexthops(rt) {
549 } endfor_nexthops(rt);
551 kfree(rt);
554 static void mpls_rt_free(struct mpls_route *rt)
556 if (rt)
557 call_rcu(&rt->rt_rcu, mpls_rt_free_rcu);
567 struct mpls_route *rt = new ? new : old;
570 if (rt && (index >= MPLS_LABEL_FIRST_UNRESERVED))
571 rtmsg_lfib(event, index, rt, nlh, net, portid, nlm_flags);
579 struct mpls_route *rt;
582 rt = mpls_dereference(net, platform_label[index]);
585 mpls_notify_route(net, index, rt, new, info);
588 mpls_rt_free(rt);
611 struct rtable *rt;
615 rt = ip_route_output(net, daddr.s_addr, 0, 0, 0, RT_SCOPE_UNIVERSE);
616 if (IS_ERR(rt))
617 return ERR_CAST(rt);
619 dev = rt->dst.dev;
621 ip_rt_put(rt);
668 struct mpls_route *rt,
676 dev = inet_fib_lookup_dev(net, nh, mpls_nh_via(rt, nh));
679 dev = inet6_fib_lookup_dev(net, nh, mpls_nh_via(rt, nh));
700 static int mpls_nh_assign_dev(struct net *net, struct mpls_route *rt,
706 dev = find_outdev(net, rt, nh, oif);
789 struct mpls_route *rt)
792 struct mpls_nh *nh = rt->rt_nh;
804 memcpy(__mpls_nh_via(rt, nh), cfg->rc_via, cfg->rc_via_alen);
807 err = mpls_nh_assign_dev(net, rt, nh, cfg->rc_ifindex);
812 rt->rt_nhn_alive--;
820 static int mpls_nh_build(struct net *net, struct mpls_route *rt,
839 __mpls_nh_via(rt, nh), extack);
846 err = mpls_nh_assign_dev(net, rt, nh, oif);
906 struct mpls_route *rt, u8 max_labels,
914 rt->rt_nhn = 0;
916 change_nexthops(rt) {
940 err = mpls_nh_build(cfg->rc_nlinfo.nl_net, rt, nh,
947 rt->rt_nhn_alive--;
950 rt->rt_nhn++;
951 } endfor_nexthops(rt);
985 struct mpls_route *rt, *old;
1039 rt = mpls_rt_alloc(nhs, max_via_alen, max_labels);
1040 if (IS_ERR(rt)) {
1041 err = PTR_ERR(rt);
1045 rt->rt_protocol = cfg->rc_protocol;
1046 rt->rt_payload_type = cfg->rc_payload_type;
1047 rt->rt_ttl_propagate = cfg->rc_ttl_propagate;
1050 err = mpls_nh_build_multi(cfg, rt, max_labels, extack);
1052 err = mpls_nh_build_from_cfg(cfg, rt);
1056 mpls_route_update(net, index, rt, &cfg->rc_nlinfo);
1061 mpls_rt_free(rt);
1518 struct mpls_route *rt;
1522 rt = mpls_route_input(net, index);
1523 if (!rt)
1529 for_nexthops(rt) {
1534 } endfor_nexthops(rt);
1537 if (deleted == rt->rt_nhn) {
1543 size_t size = sizeof(*rt) + rt->rt_nhn *
1544 rt->rt_nh_size;
1545 struct mpls_route *orig = rt;
1547 rt = kmemdup(orig, size, GFP_KERNEL);
1548 if (!rt)
1553 change_nexthops(rt) {
1580 } endfor_nexthops(rt);
1582 WRITE_ONCE(rt->rt_nhn_alive, alive);
1585 mpls_route_update(net, index, rt, NULL);
1598 struct mpls_route *rt;
1600 rt = mpls_route_input(net, index);
1601 if (!rt)
1605 change_nexthops(rt) {
1617 } endfor_nexthops(rt);
1619 WRITE_ONCE(rt->rt_nhn_alive, alive);
2023 u32 label, struct mpls_route *rt, int flags)
2039 rtm->rtm_protocol = rt->rt_protocol;
2047 if (rt->rt_ttl_propagate != MPLS_TTL_PROP_DEFAULT) {
2049 rt->rt_ttl_propagate == MPLS_TTL_PROP_ENABLED;
2055 if (rt->rt_nhn == 1) {
2056 const struct mpls_nh *nh = rt->rt_nh;
2063 nla_put_via(skb, nh->nh_via_table, mpls_nh_via(rt, nh),
2083 for_nexthops(rt) {
2108 mpls_nh_via(rt, nh),
2114 } endfor_nexthops(rt);
2116 if (linkdown == rt->rt_nhn)
2118 if (dead == rt->rt_nhn)
2192 static bool mpls_rt_uses_dev(struct mpls_route *rt,
2195 if (rt->rt_nhn == 1) {
2196 struct mpls_nh *nh = rt->rt_nh;
2201 for_nexthops(rt) {
2204 } endfor_nexthops(rt);
2250 struct mpls_route *rt;
2252 rt = rcu_dereference(platform_label[index]);
2253 if (!rt)
2256 if ((filter.dev && !mpls_rt_uses_dev(rt, filter.dev)) ||
2257 (filter.protocol && rt->rt_protocol != filter.protocol))
2262 index, rt, flags) < 0)
2276 static inline size_t lfib_nlmsg_size(struct mpls_route *rt)
2283 if (rt->rt_nhn == 1) {
2284 struct mpls_nh *nh = rt->rt_nh;
2296 for_nexthops(rt) {
2305 } endfor_nexthops(rt);
2313 static void rtmsg_lfib(int event, u32 label, struct mpls_route *rt,
2321 skb = nlmsg_new(lfib_nlmsg_size(rt), GFP_KERNEL);
2325 err = mpls_dump_route(skb, portid, seq, event, label, rt, nlm_flags);
2404 struct mpls_route *rt = NULL;
2440 rt = mpls_route_input(net, in_label);
2441 if (!rt) {
2447 skb = nlmsg_new(lfib_nlmsg_size(rt), GFP_KERNEL);
2454 RTM_NEWROUTE, in_label, rt, 0);
2506 nh = mpls_select_multipath(rt, skb);
2531 r->rtm_protocol = rt->rt_protocol;
2543 nla_put_via(skb, nh->nh_via_table, mpls_nh_via(rt, nh),
2782 struct mpls_route *rt;
2784 rt = mpls_dereference(net, platform_label[index]);
2785 mpls_notify_route(net, index, rt, NULL, NULL);
2786 mpls_rt_free(rt);