diff --git a/xio-interface.c b/xio-interface.c index 5d13b63..03d6769 100644 --- a/xio-interface.c +++ b/xio-interface.c @@ -110,6 +110,8 @@ int _xioopen_interface(const char *ifname, strncpy(sfd->para.interface.name, ifname, IFNAMSIZ); _xiointerface_get_iff(sfd->fd, ifname, &sfd->para.interface.save_iff); _xiointerface_apply_iff(sfd->fd, ifname, sfd->para.interface.iff_opts); + if (_interface_retrieve_vlan(sfd, opts) < 0) + return STAT_NORETRY; #ifdef PACKET_IGNORE_OUTGOING /* Raw socket might also provide packets that are outbound - we are not @@ -123,6 +125,25 @@ int _xioopen_interface(const char *ifname, return 0; } + +int _interface_retrieve_vlan(struct single *sfd, struct opt *opts) { +#if HAVE_STRUCT_TPACKET_AUXDATA + if (retropt_bool(opts, OPT_RETRIEVE_VLAN, + &sfd->para.socket.retrieve_vlan) + == 0) { + if (!xioparms.experimental) { + Warn1("option %s is experimental", opts->desc->defname); + } + } + if (sfd->para.socket.retrieve_vlan) { + if (_interface_setsockopt_auxdata(sfd->fd, 1) < 0) { + return -1; + } + } +#endif /* HAVE_STRUCT_TPACKET_AUXDATA */ + return 0; +} + int _interface_setsockopt_auxdata(int fd, int auxdata) { #ifdef PACKET_AUXDATA /* Linux strips VLAN tag off incoming packets and makes it available per @@ -130,6 +151,7 @@ int _interface_setsockopt_auxdata(int fd, int auxdata) { VLAN tag to be restored by Socat in the received packet */ if (auxdata) { int rc; + Info1("setsockopt(fd=%d, level=SOL_PACKET, optname=PACKET_AUXDATA)", fd); rc = Setsockopt(fd, SOL_PACKET, PACKET_AUXDATA, &auxdata, sizeof(auxdata)); if (rc < 0) { Error3("setsockopt(%d, SOL_PACKET, PACKET_AUXDATA, , {%d}): %s", diff --git a/xio-interface.h b/xio-interface.h index 19de3c9..7194ab2 100644 --- a/xio-interface.h +++ b/xio-interface.h @@ -29,6 +29,7 @@ extern const struct optdesc opt_retrieve_vlan; extern int xiolog_ancillary_packet(struct single *sfd, struct cmsghdr *cmsg, int *num, char *typbuff, int typlen, char *nambuff, int namlen, char *envbuff, int envlen, char *valbuff, int vallen); +extern int _interface_retrieve_vlan(struct single *fd, struct opt *opts); extern int _xiointerface_get_iff(int sockfd, const char *name, short *save_iff); extern int _xiointerface_set_iff(int sockfd, const char *name, short new_iff); extern int _xiointerface_apply_iff(int sockfd, const char *name, short iff_opts[2]); diff --git a/xio-tun.c b/xio-tun.c index 9aee6e3..f66be7e 100644 --- a/xio-tun.c +++ b/xio-tun.c @@ -174,6 +174,8 @@ static int xioopen_tun( applyopts_single(sfd, opts, PH_FD); _xiointerface_apply_iff(sockfd, ifr.ifr_name, sfd->para.interface.iff_opts); + if (_interface_retrieve_vlan(&xfd->stream, opts) < 0) + return STAT_NORETRY; applyopts(sfd, -1, opts, PH_FD); applyopts_cloexec(sfd->fd, opts); diff --git a/xio.h b/xio.h index ac85bb7..9af9d96 100644 --- a/xio.h +++ b/xio.h @@ -249,6 +249,7 @@ typedef struct single { #if _WITH_IP4 || _WITH_IP6 struct para_ip ip; #endif /* _WITH_IP4 || _WITH_IP6 */ + /* Copy in openssl part up to here ! */ #if HAVE_STRUCT_TPACKET_AUXDATA struct { int packet_auxdata; @@ -256,6 +257,7 @@ typedef struct single { #endif #if HAVE_STRUCT_TPACKET_AUXDATA struct tpacket_auxdata ancill_data_packet_auxdata; + bool retrieve_vlan; #endif #if WITH_UNIX struct { diff --git a/xioopts.c b/xioopts.c index 466fa92..f582785 100644 --- a/xioopts.c +++ b/xioopts.c @@ -3984,17 +3984,6 @@ int applyopt_spec( #endif /* WITH_IP6 && defined(HAVE_STRUCT_IPV6_MREQ) */ #endif /* _WITH_SOCKET */ -#if _WITH_INTERFACE - case OPT_RETRIEVE_VLAN: - if (!xioparms.experimental) { - Warn1("option %s is experimental", opt->desc->defname); - } - if (_interface_setsockopt_auxdata(fd, 1) < 0) { - return -1; - } - break; -#endif /* _WITH_INTERFACE */ - default: Error1("applyopt_spec(opt:%s): INTERNAL option not implemented", opt->desc->defname); return -1; diff --git a/xioread.c b/xioread.c index b67e2aa..b4bb530 100644 --- a/xioread.c +++ b/xioread.c @@ -235,7 +235,8 @@ ssize_t xioread(xiofile_t *file, void *buff, size_t bufsiz) { Debug3("xioread(FD=%d, ...): auxdata: flag=%d, vlan-id=%d", pipe->fd, pipe->para.socket.ancill_flag.packet_auxdata, pipe->para.socket.ancill_data_packet_auxdata.tp_vlan_tci); - if (pipe->para.socket.ancill_flag.packet_auxdata && + if (pipe->para.socket.retrieve_vlan && + pipe->para.socket.ancill_flag.packet_auxdata && pipe->para.socket.ancill_data_packet_auxdata.tp_vlan_tci != 0) { int offs = 12; /* packet type id in Ethernet header */ Debug1("xioread(%d, ...): restoring VLAN id from auxdata->tp_vlan_tci",