af-packet: remove tpacket-v1 support

Ticket: #4796.

V2 (for IDS and IPS) and V3 (for IDS) are widely supported. V2 was introduced
in 2008, so we can safely assume that all systems can run V2+.
pull/6633/head
Victor Julien 5 years ago committed by Victor Julien
parent 1f6a15cdf3
commit b9189946f9

@ -142,7 +142,7 @@ static void *ParseAFPConfig(const char *iface)
aconf->promisc = 1;
aconf->checksum_mode = CHECKSUM_VALIDATION_KERNEL;
aconf->DerefFunc = AFPDerefConfig;
aconf->flags = AFP_RING_MODE;
aconf->flags = 0;
aconf->bpf_filter = NULL;
aconf->ebpf_lb_file = NULL;
aconf->ebpf_lb_fd = -1;
@ -213,61 +213,48 @@ static void *ParseAFPConfig(const char *iface)
if (ConfGetChildValueBoolWithDefault(if_root, if_default, "use-mmap", (int *)&boolval) == 1) {
if (!boolval) {
SCLogConfig("Disabling mmaped capture on iface %s",
aconf->iface);
aconf->flags &= ~(AFP_RING_MODE|AFP_TPACKET_V3);
SCLogWarning(SC_WARN_OPTION_OBSOLETE,
"%s: \"use-mmap\" option is obsolete: mmap is always enabled", aconf->iface);
}
}
if (aconf->flags & AFP_RING_MODE) {
(void)ConfGetChildValueBoolWithDefault(if_root, if_default,
"mmap-locked", (int *)&boolval);
if (boolval) {
SCLogConfig("Enabling locked memory for mmap on iface %s",
aconf->iface);
aconf->flags |= AFP_MMAP_LOCKED;
}
(void)ConfGetChildValueBoolWithDefault(if_root, if_default, "mmap-locked", (int *)&boolval);
if (boolval) {
SCLogConfig("Enabling locked memory for mmap on iface %s", aconf->iface);
aconf->flags |= AFP_MMAP_LOCKED;
}
if (ConfGetChildValueBoolWithDefault(if_root, if_default,
"tpacket-v3", (int *)&boolval) == 1)
{
if (boolval) {
if (strcasecmp(RunmodeGetActive(), "workers") == 0) {
if (ConfGetChildValueBoolWithDefault(if_root, if_default, "tpacket-v3", (int *)&boolval) == 1) {
if (boolval) {
if (strcasecmp(RunmodeGetActive(), "workers") == 0) {
#ifdef HAVE_TPACKET_V3
SCLogConfig("Enabling tpacket v3 capture on iface %s",
aconf->iface);
aconf->flags |= AFP_TPACKET_V3;
SCLogConfig("Enabling tpacket v3 capture on iface %s", aconf->iface);
aconf->flags |= AFP_TPACKET_V3;
#else
SCLogNotice("System too old for tpacket v3 switching to v2");
aconf->flags &= ~AFP_TPACKET_V3;
SCLogNotice("System too old for tpacket v3 switching to v2");
aconf->flags &= ~AFP_TPACKET_V3;
#endif
} else {
SCLogWarning(SC_ERR_RUNMODE,
"tpacket v3 is only implemented for 'workers' runmode."
" Switching to tpacket v2.");
aconf->flags &= ~AFP_TPACKET_V3;
}
} else {
SCLogWarning(SC_ERR_RUNMODE, "tpacket v3 is only implemented for 'workers' runmode."
" Switching to tpacket v2.");
aconf->flags &= ~AFP_TPACKET_V3;
}
} else {
aconf->flags &= ~AFP_TPACKET_V3;
}
}
(void)ConfGetChildValueBoolWithDefault(if_root, if_default,
"use-emergency-flush", (int *)&boolval);
if (boolval) {
SCLogConfig("Enabling ring emergency flush on iface %s",
aconf->iface);
aconf->flags |= AFP_EMERGENCY_MODE;
}
(void)ConfGetChildValueBoolWithDefault(
if_root, if_default, "use-emergency-flush", (int *)&boolval);
if (boolval) {
SCLogConfig("Enabling ring emergency flush on iface %s", aconf->iface);
aconf->flags |= AFP_EMERGENCY_MODE;
}
if (ConfGetChildValueWithDefault(if_root, if_default, "copy-mode", &copymodestr) == 1) {
if (aconf->out_iface == NULL) {
SCLogInfo("Copy mode activated but no destination"
" iface. Disabling feature");
} else if (!(aconf->flags & AFP_RING_MODE)) {
SCLogInfo("Copy mode activated but use-mmap "
"set to no. Disabling feature");
} else if (strlen(copymodestr) <= 0) {
aconf->out_iface = NULL;
} else if (strcmp(copymodestr, "ips") == 0) {
@ -694,10 +681,7 @@ finalize:
aconf->flags |= AFP_SOCK_PROTECT;
}
if (aconf->flags & AFP_RING_MODE) {
SCLogConfig("%s: enabling zero copy mode by using data release call", iface);
}
SCLogConfig("%s: enabling zero copy mode by using data release call", iface);
return aconf;
}

@ -299,11 +299,6 @@ typedef struct AFPThreadVars_
/* IPS peer */
AFPPeer *mpeer;
/* no mmap mode */
uint8_t *data; /** Per function and thread data */
int datalen; /** Length of per function and thread data */
int cooked;
/*
* Init related members
*/
@ -622,138 +617,6 @@ static inline void AFPDumpCounters(AFPThreadVars *ptv)
#endif
}
/**
* \brief AF packet read function.
*
* This function fills
* From here the packets are picked up by the DecodeAFP thread.
*
* \param user pointer to AFPThreadVars
* \retval TM_ECODE_FAILED on failure and TM_ECODE_OK on success
*/
static int AFPRead(AFPThreadVars *ptv)
{
Packet *p = NULL;
/* XXX should try to use read that get directly to packet */
int offset = 0;
int caplen;
struct sockaddr_ll from;
struct iovec iov;
struct msghdr msg;
struct cmsghdr *cmsg;
union {
struct cmsghdr cmsg;
char buf[CMSG_SPACE(sizeof(struct tpacket_auxdata))];
} cmsg_buf;
unsigned char aux_checksum = 0;
msg.msg_name = &from;
msg.msg_namelen = sizeof(from);
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_control = &cmsg_buf;
msg.msg_controllen = sizeof(cmsg_buf);
msg.msg_flags = 0;
if (ptv->cooked)
offset = SLL_HEADER_LEN;
else
offset = 0;
iov.iov_len = ptv->datalen - offset;
iov.iov_base = ptv->data + offset;
caplen = recvmsg(ptv->socket, &msg, MSG_TRUNC);
if (caplen < 0) {
SCLogWarning(SC_ERR_AFP_READ, "recvmsg failed with error code %" PRId32,
errno);
SCReturnInt(AFP_READ_FAILURE);
}
p = PacketGetFromQueueOrAlloc();
if (p == NULL) {
SCReturnInt(AFP_SURI_FAILURE);
}
PKT_SET_SRC(p, PKT_SRC_WIRE);
#ifdef HAVE_PACKET_EBPF
if (ptv->flags & AFP_BYPASS) {
p->BypassPacketsFlow = AFPBypassCallback;
p->afp_v.v4_map_fd = ptv->v4_map_fd;
p->afp_v.v6_map_fd = ptv->v6_map_fd;
p->afp_v.nr_cpus = ptv->ebpf_t_config.cpus_count;
}
if (ptv->flags & AFP_XDPBYPASS) {
p->BypassPacketsFlow = AFPXDPBypassCallback;
p->afp_v.v4_map_fd = ptv->v4_map_fd;
p->afp_v.v6_map_fd = ptv->v6_map_fd;
p->afp_v.nr_cpus = ptv->ebpf_t_config.cpus_count;
}
#endif
/* get timestamp of packet via ioctl */
if (ioctl(ptv->socket, SIOCGSTAMP, &p->ts) == -1) {
SCLogWarning(SC_ERR_AFP_READ, "recvmsg failed with error code %" PRId32,
errno);
TmqhOutputPacketpool(ptv->tv, p);
SCReturnInt(AFP_READ_FAILURE);
}
ptv->pkts++;
p->livedev = ptv->livedev;
/* add forged header */
if (ptv->cooked) {
SllHdr * hdrp = (SllHdr *)ptv->data;
/* XXX this is minimalist, but this seems enough */
hdrp->sll_protocol = from.sll_protocol;
}
p->datalink = ptv->datalink;
SET_PKT_LEN(p, caplen + offset);
if (PacketCopyData(p, ptv->data, GET_PKT_LEN(p)) == -1) {
TmqhOutputPacketpool(ptv->tv, p);
SCReturnInt(AFP_SURI_FAILURE);
}
SCLogDebug("pktlen: %" PRIu32 " (pkt %p, pkt data %p)",
GET_PKT_LEN(p), p, GET_PKT_DATA(p));
/* We only check for checksum disable */
if (ptv->checksum_mode == CHECKSUM_VALIDATION_DISABLE) {
p->flags |= PKT_IGNORE_CHECKSUM;
} else if (ptv->checksum_mode == CHECKSUM_VALIDATION_AUTO) {
if (ChecksumAutoModeCheck(ptv->pkts,
SC_ATOMIC_GET(ptv->livedev->pkts),
SC_ATOMIC_GET(ptv->livedev->invalid_checksums))) {
ptv->checksum_mode = CHECKSUM_VALIDATION_DISABLE;
p->flags |= PKT_IGNORE_CHECKSUM;
}
} else {
aux_checksum = 1;
}
/* List is NULL if we don't have activated auxiliary data */
for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
struct tpacket_auxdata *aux;
if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct tpacket_auxdata)) ||
cmsg->cmsg_level != SOL_PACKET ||
cmsg->cmsg_type != PACKET_AUXDATA)
continue;
aux = (struct tpacket_auxdata *)CMSG_DATA(cmsg);
if (aux_checksum && (aux->tp_status & TP_STATUS_CSUMNOTREADY)) {
p->flags |= PKT_IGNORE_CHECKSUM;
}
break;
}
if (TmThreadsSlotProcessPkt(ptv->tv, ptv->slot, p) != TM_ECODE_OK) {
SCReturnInt(AFP_SURI_FAILURE);
}
SCReturnInt(AFP_READ_OK);
}
/**
* \brief AF packet write function.
*
@ -1303,49 +1166,6 @@ static void AFPSwitchState(AFPThreadVars *ptv, int state)
}
}
static int AFPReadAndDiscard(AFPThreadVars *ptv, struct timeval *synctv,
uint64_t *discarded_pkts)
{
struct sockaddr_ll from;
struct iovec iov;
struct msghdr msg;
struct timeval ts;
union {
struct cmsghdr cmsg;
char buf[CMSG_SPACE(sizeof(struct tpacket_auxdata))];
} cmsg_buf;
if (unlikely(suricata_ctl_flags != 0)) {
return 1;
}
msg.msg_name = &from;
msg.msg_namelen = sizeof(from);
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_control = &cmsg_buf;
msg.msg_controllen = sizeof(cmsg_buf);
msg.msg_flags = 0;
iov.iov_len = ptv->datalen;
iov.iov_base = ptv->data;
(void)recvmsg(ptv->socket, &msg, MSG_TRUNC);
if (ioctl(ptv->socket, SIOCGSTAMP, &ts) == -1) {
/* FIXME */
return -1;
}
if ((ts.tv_sec > synctv->tv_sec) ||
(ts.tv_sec >= synctv->tv_sec &&
ts.tv_usec > synctv->tv_usec)) {
return 1;
}
return 0;
}
static int AFPReadAndDiscardFromRing(AFPThreadVars *ptv, struct timeval *synctv,
uint64_t *discarded_pkts)
{
@ -1430,11 +1250,7 @@ static int AFPSynchronizeStart(AFPThreadVars *ptv, uint64_t *discarded_pkts)
if (AFPPeersListStarted() && synctv.tv_sec == (time_t) 0xffffffff) {
gettimeofday(&synctv, NULL);
}
if (ptv->flags & AFP_RING_MODE) {
r = AFPReadAndDiscardFromRing(ptv, &synctv, discarded_pkts);
} else {
r = AFPReadAndDiscard(ptv, &synctv, discarded_pkts);
}
r = AFPReadAndDiscardFromRing(ptv, &synctv, discarded_pkts);
SCLogDebug("Discarding on %s", ptv->tv->name);
switch (r) {
case 1:
@ -1504,14 +1320,10 @@ TmEcode ReceiveAFPLoop(ThreadVars *tv, void *data, void *slot)
ptv->slot = s->slot_next;
if (ptv->flags & AFP_RING_MODE) {
if (ptv->flags & AFP_TPACKET_V3) {
AFPReadFunc = AFPReadFromRingV3;
} else {
AFPReadFunc = AFPReadFromRing;
}
if (ptv->flags & AFP_TPACKET_V3) {
AFPReadFunc = AFPReadFromRingV3;
} else {
AFPReadFunc = AFPRead;
AFPReadFunc = AFPReadFromRing;
}
if (ptv->afp_state == AFP_STATE_DOWN) {
@ -2217,21 +2029,13 @@ static int AFPCreateSocket(AFPThreadVars *ptv, char *devname, int verbose)
}
#endif
if (ptv->flags & AFP_RING_MODE) {
ret = AFPSetupRing(ptv, devname);
if (ret != 0)
goto socket_err;
}
ret = AFPSetupRing(ptv, devname);
if (ret != 0)
goto socket_err;
SCLogDebug("Using interface '%s' via socket %d", (char *)devname, ptv->socket);
ptv->datalink = AFPGetDevLinktype(ptv->socket, ptv->iface);
switch (ptv->datalink) {
case ARPHRD_PPP:
case ARPHRD_ATM:
ptv->cooked = 1;
break;
}
TmEcode rc = AFPSetBPFFilter(ptv);
if (rc == TM_ECODE_FAILED) {
@ -2723,7 +2527,6 @@ TmEcode ReceiveAFPThreadInit(ThreadVars *tv, const void *initdata, void **data)
memset(ptv, 0, sizeof(AFPThreadVars));
ptv->tv = tv;
ptv->cooked = 0;
strlcpy(ptv->iface, afpconfig->iface, AFP_IFACE_NAME_LENGTH);
ptv->iface[AFP_IFACE_NAME_LENGTH - 1]= '\0';
@ -2815,16 +2618,6 @@ TmEcode ReceiveAFPThreadInit(ThreadVars *tv, const void *initdata, void **data)
SCReturnInt(TM_ECODE_FAILED);
}
#define T_DATA_SIZE 70000
ptv->data = SCMalloc(T_DATA_SIZE);
if (ptv->data == NULL) {
afpconfig->DerefFunc(afpconfig);
SCFree(ptv);
SCReturnInt(TM_ECODE_FAILED);
}
ptv->datalen = T_DATA_SIZE;
#undef T_DATA_SIZE
*data = (void *)ptv;
afpconfig->DerefFunc(afpconfig);
@ -2875,11 +2668,6 @@ TmEcode ReceiveAFPThreadDeinit(ThreadVars *tv, void *data)
EBPFSetupXDP(ptv->iface, -1, ptv->xdp_mode);
}
#endif
if (ptv->data != NULL) {
SCFree(ptv->data);
ptv->data = NULL;
}
ptv->datalen = 0;
ptv->bpf_filter = NULL;
if ((ptv->flags & AFP_TPACKET_V3) && ptv->ring.v3) {

@ -55,7 +55,7 @@ struct ebpf_timeout_config {
#endif
/* value for flags */
#define AFP_RING_MODE (1<<0)
// (1<<0) vacant
// (1<<1) vacant
#define AFP_SOCK_PROTECT (1<<2)
#define AFP_EMERGENCY_MODE (1<<3)

Loading…
Cancel
Save