- struct gif_softc *sc = (struct gif_softc*)ifp;
- struct ifreq *ifr = (struct ifreq*)data;
- int error = 0, size;
- struct sockaddr *sa, *dst, *src;
- const struct encaptab *p;
- struct sockaddr_in6 smask6, dmask6;
-
- switch (cmd) {
- case SIOCSIFFLAGS:
- /*
- * whenever we change our idea about multi-destination mode
- * we need to update encap attachment.
- */
- if (((ifp->if_flags ^ sc->gif_oflags) & IFF_LINK0) == 0)
- break;
- if (sc->gif_psrc == NULL || sc->gif_pdst == NULL ||
- sc->gif_psrc->sa_family != sc->gif_pdst->sa_family)
- break;
- bzero(&smask6, sizeof(smask6));
- smask6.sin6_addr.s6_addr32[0] = ~0;
- smask6.sin6_addr.s6_addr32[1] = ~0;
- smask6.sin6_addr.s6_addr32[2] = ~0;
- smask6.sin6_addr.s6_addr32[3] = ~0;
-#if 0 /* we'll need to do this soon */
- smask6.sin6_scope_id = ~0;
+ struct sockaddr_in6 *src, *dst;
+
+ src = (struct sockaddr_in6 *)sc->gif_psrc;
+ dst = (struct sockaddr_in6 *)sc->gif_pdst;
+
+ /*
+ * Check for address match. Note that the check is for an incoming
+ * packet. We should compare the *source* address in our configuration
+ * and the *destination* address of the packet, and vice versa.
+ */
+ if (!IN6_ARE_ADDR_EQUAL(&src->sin6_addr, &ip6->ip6_dst) ||
+ !IN6_ARE_ADDR_EQUAL(&dst->sin6_addr, &ip6->ip6_src))
+ return 0;
+
+ /* martian filters on outer source - done in ip6_input */
+
+ /* ingress filters on outer source */
+ if ((sc->gif_if.if_flags & IFF_LINK2) == 0 && ifp) {
+ struct sockaddr_in6 sin6;
+ struct rtentry *rt;
+
+ bzero(&sin6, sizeof(sin6));
+ sin6.sin6_family = AF_INET6;
+ sin6.sin6_len = sizeof(struct sockaddr_in6);
+ sin6.sin6_addr = ip6->ip6_src;
+#ifndef SCOPEDROUTING
+ sin6.sin6_scope_id = 0; /* XXX */