* IPv6 multicast forwarding function. This function assumes that the packet * pointed to by "ip6" has arrived on (or is about to be sent to) the interface * pointed to by "ifp", and the packet is to be relayed to other networks * that have members of the packet's destination IPv6 multicast group. * * The packet is returned unscathed to the caller, unless it is * erroneous, in which case a no
| 1063 | * context in the future. |
| 1064 | */ |
| 1065 | int |
| 1066 | X_ip6_mforward(struct ip6_hdr *ip6, struct ifnet *ifp, struct mbuf *m) |
| 1067 | { |
| 1068 | struct rtdetq *rte; |
| 1069 | struct mbuf *mb0; |
| 1070 | struct mf6c *rt; |
| 1071 | struct mif6 *mifp; |
| 1072 | struct mbuf *mm; |
| 1073 | u_long hash; |
| 1074 | mifi_t mifi; |
| 1075 | char ip6bufs[INET6_ADDRSTRLEN], ip6bufd[INET6_ADDRSTRLEN]; |
| 1076 | #ifdef UPCALL_TIMING |
| 1077 | struct timeval tp; |
| 1078 | |
| 1079 | GET_TIME(tp); |
| 1080 | #endif /* UPCALL_TIMING */ |
| 1081 | |
| 1082 | MRT6_DLOG(DEBUG_FORWARD, "src %s, dst %s, ifindex %d", |
| 1083 | ip6_sprintf(ip6bufs, &ip6->ip6_src), |
| 1084 | ip6_sprintf(ip6bufd, &ip6->ip6_dst), ifp->if_index); |
| 1085 | |
| 1086 | /* |
| 1087 | * Don't forward a packet with Hop limit of zero or one, |
| 1088 | * or a packet destined to a local-only group. |
| 1089 | */ |
| 1090 | if (ip6->ip6_hlim <= 1 || IN6_IS_ADDR_MC_INTFACELOCAL(&ip6->ip6_dst) || |
| 1091 | IN6_IS_ADDR_MC_LINKLOCAL(&ip6->ip6_dst)) |
| 1092 | return (0); |
| 1093 | ip6->ip6_hlim--; |
| 1094 | |
| 1095 | /* |
| 1096 | * Source address check: do not forward packets with unspecified |
| 1097 | * source. It was discussed in July 2000, on ipngwg mailing list. |
| 1098 | * This is rather more serious than unicast cases, because some |
| 1099 | * MLD packets can be sent with the unspecified source address |
| 1100 | * (although such packets must normally set 1 to the hop limit field). |
| 1101 | */ |
| 1102 | if (IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_src)) { |
| 1103 | IP6STAT_INC(ip6s_cantforward); |
| 1104 | if (V_ip6_log_time + V_ip6_log_interval < time_uptime) { |
| 1105 | V_ip6_log_time = time_uptime; |
| 1106 | log(LOG_DEBUG, |
| 1107 | "cannot forward " |
| 1108 | "from %s to %s nxt %d received on %s\n", |
| 1109 | ip6_sprintf(ip6bufs, &ip6->ip6_src), |
| 1110 | ip6_sprintf(ip6bufd, &ip6->ip6_dst), |
| 1111 | ip6->ip6_nxt, |
| 1112 | if_name(m->m_pkthdr.rcvif)); |
| 1113 | } |
| 1114 | return (0); |
| 1115 | } |
| 1116 | |
| 1117 | MFC6_LOCK(); |
| 1118 | |
| 1119 | /* |
| 1120 | * Determine forwarding mifs from the forwarding cache table |
| 1121 | */ |
| 1122 | MF6CFIND(ip6->ip6_src, ip6->ip6_dst, rt); |
nothing calls this directly
no test coverage detected