diff options
author | ae <ae@FreeBSD.org> | 2015-05-31 22:58:41 +0000 |
---|---|---|
committer | ae <ae@FreeBSD.org> | 2015-05-31 22:58:41 +0000 |
commit | 8272d42d32e60c174d7f98100455a165072a5227 (patch) | |
tree | 98524870290325811fda8d0a14480a98c04ddbec /sys | |
parent | b6f9f373d088040e2409bc6d7f0ae7b3d1644cf7 (diff) | |
download | FreeBSD-src-8272d42d32e60c174d7f98100455a165072a5227.zip FreeBSD-src-8272d42d32e60c174d7f98100455a165072a5227.tar.gz |
MFC r282965:
Add an ability accept encapsulated packets from different sources by one
gif(4) interface. Add new option "ignore_source" for gif(4) interface.
When it is enabled, gif's encapcheck function requires match only for
packet's destination address.
Differential Revision: https://reviews.freebsd.org/D2004
Sponsored by: Yandex LLC
Diffstat (limited to 'sys')
-rw-r--r-- | sys/net/if_gif.h | 4 | ||||
-rw-r--r-- | sys/netinet/in_gif.c | 12 | ||||
-rw-r--r-- | sys/netinet6/in6_gif.c | 12 |
3 files changed, 21 insertions, 7 deletions
diff --git a/sys/net/if_gif.h b/sys/net/if_gif.h index 8986a20..eebdf4c 100644 --- a/sys/net/if_gif.h +++ b/sys/net/if_gif.h @@ -117,7 +117,9 @@ int gif_encapcheck(const struct mbuf *, int, int, void *); #define GIFSOPTS _IOW('i', 151, struct ifreq) #define GIF_ACCEPT_REVETHIP 0x0001 +#define GIF_IGNORE_SOURCE 0x0002 #define GIF_SEND_REVETHIP 0x0010 -#define GIF_OPTMASK (GIF_ACCEPT_REVETHIP|GIF_SEND_REVETHIP) +#define GIF_OPTMASK (GIF_ACCEPT_REVETHIP|GIF_SEND_REVETHIP| \ + GIF_IGNORE_SOURCE) #endif /* _NET_IF_GIF_H_ */ diff --git a/sys/netinet/in_gif.c b/sys/netinet/in_gif.c index c4df3b3..832c233 100644 --- a/sys/netinet/in_gif.c +++ b/sys/netinet/in_gif.c @@ -177,13 +177,19 @@ in_gif_input(struct mbuf **mp, int *offp, int proto) static int gif_validate4(const struct ip *ip, struct gif_softc *sc, struct ifnet *ifp) { + int ret; GIF_RLOCK_ASSERT(sc); /* check for address match */ - if (sc->gif_iphdr->ip_src.s_addr != ip->ip_dst.s_addr || - sc->gif_iphdr->ip_dst.s_addr != ip->ip_src.s_addr) + if (sc->gif_iphdr->ip_src.s_addr != ip->ip_dst.s_addr) return (0); + ret = 32; + if (sc->gif_iphdr->ip_dst.s_addr != ip->ip_src.s_addr) { + if ((sc->gif_options & GIF_IGNORE_SOURCE) == 0) + return (0); + } else + ret += 32; /* martian filters on outer source - NOT done in ip_input! */ if (IN_MULTICAST(ntohl(ip->ip_src.s_addr))) @@ -214,7 +220,7 @@ gif_validate4(const struct ip *ip, struct gif_softc *sc, struct ifnet *ifp) } RTFREE_LOCKED(rt); } - return (32 * 2); + return (ret); } /* diff --git a/sys/netinet6/in6_gif.c b/sys/netinet6/in6_gif.c index 1872f5c..002bf53 100644 --- a/sys/netinet6/in6_gif.c +++ b/sys/netinet6/in6_gif.c @@ -180,6 +180,7 @@ static int gif_validate6(const struct ip6_hdr *ip6, struct gif_softc *sc, struct ifnet *ifp) { + int ret; GIF_RLOCK_ASSERT(sc); /* @@ -187,9 +188,14 @@ gif_validate6(const struct ip6_hdr *ip6, struct gif_softc *sc, * 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(&sc->gif_ip6hdr->ip6_src, &ip6->ip6_dst) || - !IN6_ARE_ADDR_EQUAL(&sc->gif_ip6hdr->ip6_dst, &ip6->ip6_src)) + if (!IN6_ARE_ADDR_EQUAL(&sc->gif_ip6hdr->ip6_src, &ip6->ip6_dst)) return (0); + ret = 128; + if (!IN6_ARE_ADDR_EQUAL(&sc->gif_ip6hdr->ip6_dst, &ip6->ip6_src)) { + if ((sc->gif_options & GIF_IGNORE_SOURCE) == 0) + return (0); + } else + ret += 128; /* martian filters on outer source - done in ip6_input */ @@ -214,7 +220,7 @@ gif_validate6(const struct ip6_hdr *ip6, struct gif_softc *sc, RTFREE_LOCKED(rt); } - return (128 * 2); + return (ret); } /* |