* Creates rtentry and nexthop based on @info data. * Return 0 and fills in rtentry into @prt on success, * return errno otherwise. */
| 573 | * return errno otherwise. |
| 574 | */ |
| 575 | static int |
| 576 | create_rtentry(struct rib_head *rnh, struct rt_addrinfo *info, |
| 577 | struct rtentry **prt) |
| 578 | { |
| 579 | struct sockaddr *dst, *ndst, *gateway, *netmask; |
| 580 | struct rtentry *rt; |
| 581 | struct nhop_object *nh; |
| 582 | struct ifaddr *ifa; |
| 583 | int error, flags; |
| 584 | |
| 585 | dst = info->rti_info[RTAX_DST]; |
| 586 | gateway = info->rti_info[RTAX_GATEWAY]; |
| 587 | netmask = info->rti_info[RTAX_NETMASK]; |
| 588 | flags = info->rti_flags; |
| 589 | |
| 590 | if ((flags & RTF_GATEWAY) && !gateway) |
| 591 | return (EINVAL); |
| 592 | if (dst && gateway && (dst->sa_family != gateway->sa_family) && |
| 593 | (gateway->sa_family != AF_UNSPEC) && (gateway->sa_family != AF_LINK)) |
| 594 | return (EINVAL); |
| 595 | |
| 596 | if (dst->sa_len > sizeof(((struct rtentry *)NULL)->rt_dstb)) |
| 597 | return (EINVAL); |
| 598 | |
| 599 | if (info->rti_ifa == NULL) { |
| 600 | error = rt_getifa_fib(info, rnh->rib_fibnum); |
| 601 | if (error) |
| 602 | return (error); |
| 603 | } else { |
| 604 | ifa_ref(info->rti_ifa); |
| 605 | } |
| 606 | |
| 607 | error = nhop_create_from_info(rnh, info, &nh); |
| 608 | ifa_free(info->rti_ifa); |
| 609 | if (error != 0) |
| 610 | return (error); |
| 611 | |
| 612 | rt = uma_zalloc(V_rtzone, M_NOWAIT | M_ZERO); |
| 613 | if (rt == NULL) { |
| 614 | nhop_free(nh); |
| 615 | return (ENOBUFS); |
| 616 | } |
| 617 | rt->rte_flags = (RTF_UP | flags) & RTE_RT_FLAG_MASK; |
| 618 | rt->rt_nhop = nh; |
| 619 | |
| 620 | /* Fill in dst */ |
| 621 | memcpy(&rt->rt_dst, dst, dst->sa_len); |
| 622 | rt_key(rt) = &rt->rt_dst; |
| 623 | |
| 624 | /* |
| 625 | * point to the (possibly newly malloc'd) dest address. |
| 626 | */ |
| 627 | ndst = (struct sockaddr *)rt_key(rt); |
| 628 | |
| 629 | /* |
| 630 | * make sure it contains the value we want (masked if needed). |
| 631 | */ |
| 632 | if (netmask) { |
no test coverage detected