Changeset View
Changeset View
Standalone View
Standalone View
sys/netinet/ip_output.c
| Show First 20 Lines • Show All 102 Lines • ▼ Show 20 Lines | |||||
| extern int in_mcast_loop; | extern int in_mcast_loop; | ||||
| extern struct protosw inetsw[]; | extern struct protosw inetsw[]; | ||||
| static inline int | static inline int | ||||
| ip_output_pfil(struct mbuf **mp, struct ifnet *ifp, struct inpcb *inp, | ip_output_pfil(struct mbuf **mp, struct ifnet *ifp, struct inpcb *inp, | ||||
| struct sockaddr_in *dst, int *fibnum, int *error) | struct sockaddr_in *dst, int *fibnum, int *error) | ||||
| { | { | ||||
| struct m_tag *fwd_tag = NULL; | |||||
| struct mbuf *m; | struct mbuf *m; | ||||
| struct in_addr odst; | struct in_addr odst; | ||||
| struct ip *ip; | struct ip *ip; | ||||
| m = *mp; | m = *mp; | ||||
| ip = mtod(m, struct ip *); | ip = mtod(m, struct ip *); | ||||
| /* Run through list of hooks for output packets. */ | /* Run through list of hooks for output packets. */ | ||||
| ▲ Show 20 Lines • Show All 57 Lines • ▼ Show 20 Lines | |||||
| #endif | #endif | ||||
| m->m_pkthdr.csum_flags |= | m->m_pkthdr.csum_flags |= | ||||
| CSUM_IP_CHECKED | CSUM_IP_VALID; | CSUM_IP_CHECKED | CSUM_IP_VALID; | ||||
| *error = netisr_queue(NETISR_IP, m); | *error = netisr_queue(NETISR_IP, m); | ||||
| return 1; /* Finished */ | return 1; /* Finished */ | ||||
| } | } | ||||
| /* Or forward to some other address? */ | /* Or forward to some other address? */ | ||||
| if ((m->m_flags & M_IP_NEXTHOP) && | if (IP_HAS_NEXTHOP(m) && !ip_get_fwdtag(m, dst, NULL)) { | ||||
| ((fwd_tag = m_tag_find(m, PACKET_TAG_IPFORWARD, NULL)) != NULL)) { | |||||
| bcopy((fwd_tag+1), dst, sizeof(struct sockaddr_in)); | |||||
| m->m_flags |= M_SKIP_FIREWALL; | m->m_flags |= M_SKIP_FIREWALL; | ||||
| m->m_flags &= ~M_IP_NEXTHOP; | ip_flush_fwdtag(m); | ||||
| m_tag_delete(m, fwd_tag); | |||||
| return -1; /* Reloop for CHANGE of dst */ | return -1; /* Reloop for CHANGE of dst */ | ||||
| } | } | ||||
| return 0; | return 0; | ||||
| } | } | ||||
| /* | /* | ||||
| * IP output. The packet in mbuf chain m contains a skeletal IP | * IP output. The packet in mbuf chain m contains a skeletal IP | ||||
| ▲ Show 20 Lines • Show All 1,208 Lines • ▼ Show 20 Lines | if (copym != NULL) { | ||||
| /* | /* | ||||
| * We don't bother to fragment if the IP length is greater | * We don't bother to fragment if the IP length is greater | ||||
| * than the interface's MTU. Can this possibly matter? | * than the interface's MTU. Can this possibly matter? | ||||
| */ | */ | ||||
| ip = mtod(copym, struct ip *); | ip = mtod(copym, struct ip *); | ||||
| ip->ip_sum = 0; | ip->ip_sum = 0; | ||||
| ip->ip_sum = in_cksum(copym, hlen); | ip->ip_sum = in_cksum(copym, hlen); | ||||
| if_simloop(ifp, copym, AF_INET, 0); | if_simloop(ifp, copym, AF_INET, 0); | ||||
| } | |||||
| } | |||||
| int | |||||
| ip_set_fwdtag(struct mbuf *m, struct sockaddr_in *dst, u_short ifidx) | |||||
| { | |||||
| struct sockaddr_in *sa; | |||||
| struct m_tag *fwd_tag; | |||||
| (void)ifidx; /* XXX: store after dst, or make struct? */ | |||||
| KASSERT(dst != NULL, ("%s: !dst", __func__)); | |||||
| KASSERT(dst->sin_family == AF_INET, ("%s: !AF_INET", __func__)); | |||||
| fwd_tag = m_tag_find(m, PACKET_TAG_IPFORWARD, NULL); | |||||
| if (fwd_tag != NULL) { | |||||
| KASSERT(((struct sockaddr *)(fwd_tag+1))->sa_family == | |||||
| AF_INET, ("%s: !AF_INET", __func__)); | |||||
| m_tag_unlink(m, fwd_tag); | |||||
| } else { | |||||
| fwd_tag = m_tag_get(PACKET_TAG_IPFORWARD, sizeof(*dst), | |||||
ae: I think return error code is better than magic value. How about (ENOBUFS)? | |||||
| M_NOWAIT); | |||||
| if (fwd_tag == NULL) { | |||||
| return (ENOBUFS); | |||||
| } | |||||
| } | |||||
Done Inline ActionsI think it would be good add KASSERT(dst->sin_family == AF_INET) for consistency. ae: I think it would be good add KASSERT(dst->sin_family == AF_INET) for consistency. | |||||
| sa = (struct sockaddr_in *)(fwd_tag+1); | |||||
| bcopy(dst, sa, sizeof(*dst)); | |||||
| m->m_flags |= M_IP_NEXTHOP; | |||||
| if (in_localip(sa->sin_addr)) | |||||
| m->m_flags |= M_FASTFWD_OURS; | |||||
| else | |||||
| m->m_flags &= ~M_FASTFWD_OURS; | |||||
Done Inline Actions"Values in return statements should be enclosed in parentheses." (c) style(9) :-) ae: "Values in return statements should be enclosed in parentheses." (c) style(9) :-) | |||||
| m_tag_prepend(m, fwd_tag); | |||||
| return (0); | |||||
| } | |||||
| int | |||||
| ip_get_fwdtag(struct mbuf *m, struct sockaddr_in *dst, u_short *ifidx) | |||||
| { | |||||
| struct m_tag *fwd_tag; | |||||
Done Inline ActionsENOENT/ESRCH ae: ENOENT/ESRCH | |||||
| fwd_tag = m_tag_find(m, PACKET_TAG_IPFORWARD, NULL); | |||||
| if (fwd_tag == NULL) { | |||||
| return (ENOENT); | |||||
| } | |||||
| KASSERT(((struct sockaddr *)(fwd_tag+1))->sa_family == AF_INET, | |||||
| ("%s: !AF_INET", __func__)); | |||||
| if (dst != NULL) { | |||||
| bcopy((fwd_tag+1), dst, sizeof(*dst)); | |||||
| } | |||||
| if (ifidx != NULL) { | |||||
| /* XXX ifidx is not yet defined */ | |||||
| } | |||||
| return (0); | |||||
| } | |||||
| void | |||||
| ip_flush_fwdtag(struct mbuf *m) | |||||
| { | |||||
| struct m_tag *fwd_tag; | |||||
| fwd_tag = m_tag_find(m, PACKET_TAG_IPFORWARD, NULL); | |||||
| if (fwd_tag != NULL) { | |||||
| KASSERT(((struct sockaddr *)(fwd_tag+1))->sa_family == | |||||
| AF_INET, ("%s: !AF_INET", __func__)); | |||||
| m->m_flags &= ~(M_IP_NEXTHOP | M_FASTFWD_OURS); | |||||
| m_tag_delete(m, fwd_tag); | |||||
| } | } | ||||
| } | } | ||||
I think return error code is better than magic value. How about (ENOBUFS)?