* Set IPv6 outgoing packet options based on advanced API. */
| 2817 | * Set IPv6 outgoing packet options based on advanced API. |
| 2818 | */ |
| 2819 | int |
| 2820 | ip6_setpktopts(struct mbuf *control, struct ip6_pktopts *opt, |
| 2821 | struct ip6_pktopts *stickyopt, struct ucred *cred, int uproto) |
| 2822 | { |
| 2823 | struct cmsghdr *cm = NULL; |
| 2824 | |
| 2825 | if (control == NULL || opt == NULL) |
| 2826 | return (EINVAL); |
| 2827 | |
| 2828 | ip6_initpktopts(opt); |
| 2829 | if (stickyopt) { |
| 2830 | int error; |
| 2831 | |
| 2832 | /* |
| 2833 | * If stickyopt is provided, make a local copy of the options |
| 2834 | * for this particular packet, then override them by ancillary |
| 2835 | * objects. |
| 2836 | * XXX: copypktopts() does not copy the cached route to a next |
| 2837 | * hop (if any). This is not very good in terms of efficiency, |
| 2838 | * but we can allow this since this option should be rarely |
| 2839 | * used. |
| 2840 | */ |
| 2841 | if ((error = copypktopts(opt, stickyopt, M_NOWAIT)) != 0) |
| 2842 | return (error); |
| 2843 | } |
| 2844 | |
| 2845 | /* |
| 2846 | * XXX: Currently, we assume all the optional information is stored |
| 2847 | * in a single mbuf. |
| 2848 | */ |
| 2849 | if (control->m_next) |
| 2850 | return (EINVAL); |
| 2851 | |
| 2852 | for (; control->m_len > 0; control->m_data += CMSG_ALIGN(cm->cmsg_len), |
| 2853 | control->m_len -= CMSG_ALIGN(cm->cmsg_len)) { |
| 2854 | int error; |
| 2855 | |
| 2856 | if (control->m_len < CMSG_LEN(0)) |
| 2857 | return (EINVAL); |
| 2858 | |
| 2859 | cm = mtod(control, struct cmsghdr *); |
| 2860 | if (cm->cmsg_len == 0 || cm->cmsg_len > control->m_len) |
| 2861 | return (EINVAL); |
| 2862 | if (cm->cmsg_level != IPPROTO_IPV6) |
| 2863 | continue; |
| 2864 | |
| 2865 | error = ip6_setpktopt(cm->cmsg_type, CMSG_DATA(cm), |
| 2866 | cm->cmsg_len - CMSG_LEN(0), opt, cred, 0, 1, uproto); |
| 2867 | if (error) |
| 2868 | return (error); |
| 2869 | } |
| 2870 | |
| 2871 | return (0); |
| 2872 | } |
| 2873 | |
| 2874 | /* |
| 2875 | * Set a particular packet option, as a sticky option or an ancillary data |
no test coverage detected