Optimizations to reduce branch misses

pull/607/head
Victor Julien 12 years ago
parent 64f5129f12
commit 49087f21e4

@ -406,7 +406,7 @@ TmEcode Unified2Alert (ThreadVars *t, Packet *p, void *data, PacketQueue *pq, Pa
Unified2AlertThread *aun = (Unified2AlertThread *)data;
aun->xff_flags = UNIFIED2_ALERT_XFF_DISABLED;
if (p->alerts.cnt == 0 && !(p->flags & PKT_HAS_TAG))
if (likely(p->alerts.cnt == 0 && !(p->flags & PKT_HAS_TAG)))
return TM_ECODE_OK;
/* overwrite mode can only work per u2 block, not per individual
@ -878,17 +878,19 @@ int Unified2IPv6TypeAlert (ThreadVars *t, Packet *p, void *data, PacketQueue *pq
{
Unified2AlertThread *aun = (Unified2AlertThread *)data;
Unified2AlertFileHeader hdr;
AlertIPv6Unified2 *phdr = (AlertIPv6Unified2 *)(aun->data +
sizeof(Unified2AlertFileHeader));
AlertIPv6Unified2 *phdr;
AlertIPv6Unified2 gphdr;
PacketAlert *pa;
int offset, length;
int ret;
unsigned int event_id;
if (p->alerts.cnt == 0 && !(p->flags & PKT_HAS_TAG))
if (likely(p->alerts.cnt == 0 && !(p->flags & PKT_HAS_TAG)))
return 0;
phdr = (AlertIPv6Unified2 *)(aun->data +
sizeof(Unified2AlertFileHeader));
length = (sizeof(Unified2AlertFileHeader) + sizeof(AlertIPv6Unified2));
offset = length;
@ -1062,17 +1064,19 @@ int Unified2IPv4TypeAlert (ThreadVars *tv, Packet *p, void *data, PacketQueue *p
{
Unified2AlertThread *aun = (Unified2AlertThread *)data;
Unified2AlertFileHeader hdr;
AlertIPv4Unified2 *phdr = (AlertIPv4Unified2 *)(aun->data +
sizeof(Unified2AlertFileHeader));
AlertIPv4Unified2 *phdr;
AlertIPv4Unified2 gphdr;
PacketAlert *pa;
int offset, length;
int ret;
unsigned int event_id;
if (p->alerts.cnt == 0 && !(p->flags & PKT_HAS_TAG))
if (likely(p->alerts.cnt == 0 && !(p->flags & PKT_HAS_TAG)))
return 0;
phdr = (AlertIPv4Unified2 *)(aun->data +
sizeof(Unified2AlertFileHeader));
length = (sizeof(Unified2AlertFileHeader) + sizeof(AlertIPv4Unified2));
offset = length;

@ -42,13 +42,13 @@ void DecodeEthernet(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *p
{
SCPerfCounterIncr(dtv->counter_eth, tv->sc_perf_pca);
if (len < ETHERNET_HEADER_LEN) {
if (unlikely(len < ETHERNET_HEADER_LEN)) {
ENGINE_SET_EVENT(p,ETHERNET_PKT_TOO_SMALL);
return;
}
p->ethh = (EthernetHdr *)pkt;
if (p->ethh == NULL)
if (unlikely(p->ethh == NULL))
return;
SCLogDebug("p %p pkt %p ether type %04x", p, pkt, ntohs(p->ethh->eth_type));

@ -102,13 +102,13 @@ static int IPV4OptValidateRoute(Packet *p, const IPV4Opt *o) {
uint8_t ptr;
/* Check length */
if (o->len < IPV4_OPT_ROUTE_MIN) {
if (unlikely(o->len < IPV4_OPT_ROUTE_MIN)) {
ENGINE_SET_EVENT(p,IPV4_OPT_INVALID_LEN);
return -1;
}
/* Data is required */
if (o->data == NULL) {
if (unlikely(o->data == NULL)) {
ENGINE_SET_EVENT(p,IPV4_OPT_MALFORMED);
return -1;
}
@ -118,7 +118,7 @@ static int IPV4OptValidateRoute(Packet *p, const IPV4Opt *o) {
* must be a incremented by 4 bytes (address size) and cannot extend
* past option length.
*/
if ((ptr < 4) || (ptr % 4) || (ptr > o->len + 1)) {
if (unlikely((ptr < 4) || (ptr % 4) || (ptr > o->len + 1))) {
ENGINE_SET_EVENT(p,IPV4_OPT_MALFORMED);
return -1;
}
@ -139,20 +139,20 @@ static int IPV4OptValidateTimestamp(Packet *p, const IPV4Opt *o) {
uint8_t rec_size;
/* Check length */
if (o->len < IPV4_OPT_TS_MIN) {
if (unlikely(o->len < IPV4_OPT_TS_MIN)) {
ENGINE_SET_EVENT(p,IPV4_OPT_INVALID_LEN);
return -1;
}
/* Data is required */
if (o->data == NULL) {
if (unlikely(o->data == NULL)) {
ENGINE_SET_EVENT(p,IPV4_OPT_MALFORMED);
return -1;
}
ptr = *o->data;
/* We need the flag to determine what is in the option payload */
if (ptr < 5) {
if (unlikely(ptr < 5)) {
ENGINE_SET_EVENT(p,IPV4_OPT_MALFORMED);
return -1;
}
@ -165,7 +165,7 @@ static int IPV4OptValidateTimestamp(Packet *p, const IPV4Opt *o) {
* type+len+ptr+ovfl+flag, must be incremented by by the rec_size
* and cannot extend past option length.
*/
if (((ptr - 5) % rec_size) || (ptr > o->len + 1)) {
if (unlikely(((ptr - 5) % rec_size) || (ptr > o->len + 1))) {
ENGINE_SET_EVENT(p,IPV4_OPT_MALFORMED);
return -1;
}
@ -186,13 +186,13 @@ static int IPV4OptValidateCIPSO(Packet *p, const IPV4Opt *o) {
uint16_t len;
/* Check length */
if (o->len < IPV4_OPT_CIPSO_MIN) {
if (unlikely(o->len < IPV4_OPT_CIPSO_MIN)) {
ENGINE_SET_EVENT(p,IPV4_OPT_INVALID_LEN);
return -1;
}
/* Data is required */
if (o->data == NULL) {
if (unlikely(o->data == NULL)) {
ENGINE_SET_EVENT(p,IPV4_OPT_MALFORMED);
return -1;
}
@ -201,14 +201,14 @@ static int IPV4OptValidateCIPSO(Packet *p, const IPV4Opt *o) {
len = o->len - 1 - 1 - 4; /* Length of tags after header */
#if 0
/* Domain of Interest (DOI) of 0 is reserved and thus invalid */
/** \todo Aparently a DOI of zero is fine in practice - verify. */
if (doi == 0) {
#if 0
ENGINE_SET_EVENT(p,IPV4_OPT_MALFORMED);
return -1;
#endif
}
#endif
/* NOTE: We know len has passed min tests prior to this call */
@ -220,7 +220,7 @@ static int IPV4OptValidateCIPSO(Packet *p, const IPV4Opt *o) {
uint8_t tlen;
/* Tag header must fit within option length */
if (len < 2) {
if (unlikely(len < 2)) {
//printf("CIPSO tag header too large %" PRIu16 " < 2\n", len);
ENGINE_SET_EVENT(p,IPV4_OPT_MALFORMED);
return -1;
@ -231,25 +231,20 @@ static int IPV4OptValidateCIPSO(Packet *p, const IPV4Opt *o) {
tlen = *(tag++);
/* Tag length must fit within the option length */
if (tlen > len) {
if (unlikely(tlen > len)) {
//printf("CIPSO tag len too large %" PRIu8 " > %" PRIu16 "\n", tlen, len);
ENGINE_SET_EVENT(p,IPV4_OPT_MALFORMED);
return -1;
}
switch(ttype) {
case 0:
/* Tag type 0 is reserved and thus invalid */
/** \todo Wireshark marks this a padding, but spec says reserved. */
ENGINE_SET_EVENT(p,IPV4_OPT_MALFORMED);
return -1;
case 1:
case 2:
case 5:
case 6:
case 7:
/* Tag is at least 4 and at most the remainder of option len */
if ((tlen < 4) || (tlen > len)) {
if (unlikely((tlen < 4) || (tlen > len))) {
//printf("CIPSO tag %" PRIu8 " bad tlen=%" PRIu8 " len=%" PRIu8 "\n", ttype, tlen, len);
ENGINE_SET_EVENT(p,IPV4_OPT_MALFORMED);
return -1;
@ -258,7 +253,7 @@ static int IPV4OptValidateCIPSO(Packet *p, const IPV4Opt *o) {
/* The alignment octet is always 0 except tag
* type 7, which has no such field.
*/
if ((ttype != 7) && (*tag != 0)) {
if (unlikely((ttype != 7) && (*tag != 0))) {
//printf("CIPSO tag %" PRIu8 " ao=%" PRIu8 "\n", ttype, tlen);
ENGINE_SET_EVENT(p,IPV4_OPT_MALFORMED);
return -1;
@ -269,6 +264,11 @@ static int IPV4OptValidateCIPSO(Packet *p, const IPV4Opt *o) {
len -= tlen;
continue;
case 0:
/* Tag type 0 is reserved and thus invalid */
/** \todo Wireshark marks this a padding, but spec says reserved. */
ENGINE_SET_EVENT(p,IPV4_OPT_MALFORMED);
return -1;
default:
//printf("CIPSO tag %" PRIu8 " unknown tag\n", ttype);
ENGINE_SET_EVENT(p,IPV4_OPT_MALFORMED);
@ -324,7 +324,7 @@ static int DecodeIPV4Options(Packet *p, uint8_t *pkt, uint16_t len)
/* multibyte options */
} else {
if (plen < 2) {
if (unlikely(plen < 2)) {
/** \todo What if padding is non-zero (possible covert channel or data leakage)? */
/** \todo Spec seems to indicate EOL required if there is padding */
ENGINE_SET_EVENT(p,IPV4_OPT_EOL_REQUIRED);
@ -332,7 +332,7 @@ static int DecodeIPV4Options(Packet *p, uint8_t *pkt, uint16_t len)
}
/* Option length is too big for packet */
if (*(pkt+1) > plen) {
if (unlikely(*(pkt+1) > plen)) {
ENGINE_SET_EVENT(p,IPV4_OPT_INVALID_LEN);
return -1;
}
@ -351,8 +351,8 @@ static int DecodeIPV4Options(Packet *p, uint8_t *pkt, uint16_t len)
/* we already know that the total options len is valid,
* so here the len of the specific option must be bad.
* Also check for invalid lengths 0 and 1. */
if (p->IPV4_OPTS[p->IPV4_OPTS_CNT].len > plen ||
p->IPV4_OPTS[p->IPV4_OPTS_CNT].len < 2) {
if (unlikely(p->IPV4_OPTS[p->IPV4_OPTS_CNT].len > plen ||
p->IPV4_OPTS[p->IPV4_OPTS_CNT].len < 2)) {
ENGINE_SET_EVENT(p,IPV4_OPT_INVALID_LEN);
return -1;
}

@ -88,9 +88,9 @@ static void DecodeIP6inIP6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uin
return;
}
if (IP_GET_RAW_VER(pkt) == 6) {
if (pq != NULL) {
if (unlikely(pq != NULL)) {
Packet *tp = PacketPseudoPktSetup(p, pkt, plen, IPPROTO_IPV6);
if (tp != NULL) {
if (unlikely(tp != NULL)) {
PKT_SET_SRC(tp, PKT_SRC_DECODER_IPV6);
DecodeTunnel(tv, dtv, tp, GET_PKT_DATA(tp),
GET_PKT_LEN(tp), pq, IPPROTO_IPV6);
@ -504,11 +504,11 @@ DecodeIPV6ExtHdrs(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt
static int DecodeIPV6Packet (ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len)
{
if (len < IPV6_HEADER_LEN) {
if (unlikely(len < IPV6_HEADER_LEN)) {
return -1;
}
if (IP_GET_RAW_VER(pkt) != 6) {
if (unlikely(IP_GET_RAW_VER(pkt) != 6)) {
SCLogDebug("wrong ip version %" PRIu8 "",IP_GET_RAW_VER(pkt));
ENGINE_SET_EVENT(p,IPV6_WRONG_IP_VER);
return -1;
@ -516,7 +516,7 @@ static int DecodeIPV6Packet (ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, u
p->ip6h = (IPV6Hdr *)pkt;
if (len < (IPV6_HEADER_LEN + IPV6_GET_PLEN(p)))
if (unlikely(len < (IPV6_HEADER_LEN + IPV6_GET_PLEN(p))))
{
ENGINE_SET_EVENT(p,IPV6_TRUNC_PKT);
return -1;
@ -536,7 +536,7 @@ void DecodeIPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt,
/* do the actual decoding */
ret = DecodeIPV6Packet (tv, dtv, p, pkt, len);
if (ret < 0) {
if (unlikely(ret < 0)) {
p->ip6h = NULL;
return;
}

@ -44,13 +44,13 @@ void DecodePPP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, u
{
SCPerfCounterIncr(dtv->counter_ppp, tv->sc_perf_pca);
if(len < PPP_HEADER_LEN) {
if (unlikely(len < PPP_HEADER_LEN)) {
ENGINE_SET_EVENT(p,PPP_PKT_TOO_SMALL);
return;
}
p->ppph = (PPPHdr *)pkt;
if(p->ppph == NULL)
if (unlikely(p->ppph == NULL))
return;
SCLogDebug("p %p pkt %p PPP protocol %04x Len: %" PRId32 "",
@ -58,6 +58,36 @@ void DecodePPP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, u
switch (ntohs(p->ppph->protocol))
{
case PPP_VJ_UCOMP:
if (unlikely(len < (PPP_HEADER_LEN + IPV4_HEADER_LEN))) {
ENGINE_SET_EVENT(p,PPPVJU_PKT_TOO_SMALL);
return;
}
if (likely(IPV4_GET_RAW_VER((IPV4Hdr *)(pkt + PPP_HEADER_LEN)) == 4)) {
DecodeIPV4(tv, dtv, p, pkt + PPP_HEADER_LEN, len - PPP_HEADER_LEN, pq);
}
break;
case PPP_IP:
if (unlikely(len < (PPP_HEADER_LEN + IPV4_HEADER_LEN))) {
ENGINE_SET_EVENT(p,PPPIPV4_PKT_TOO_SMALL);
return;
}
DecodeIPV4(tv, dtv, p, pkt + PPP_HEADER_LEN, len - PPP_HEADER_LEN, pq);
break;
/* PPP IPv6 was not tested */
case PPP_IPV6:
if (unlikely(len < (PPP_HEADER_LEN + IPV6_HEADER_LEN))) {
ENGINE_SET_EVENT(p,PPPIPV6_PKT_TOO_SMALL);
return;
}
DecodeIPV6(tv, dtv, p, pkt + PPP_HEADER_LEN, len - PPP_HEADER_LEN, pq);
break;
case PPP_VJ_COMP:
case PPP_IPX:
case PPP_OSI:
@ -89,37 +119,6 @@ void DecodePPP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, u
ENGINE_SET_EVENT(p,PPP_UNSUP_PROTO);
break;
case PPP_VJ_UCOMP:
if(len < (PPP_HEADER_LEN + IPV4_HEADER_LEN)) {
ENGINE_SET_EVENT(p,PPPVJU_PKT_TOO_SMALL);
return;
}
if(IPV4_GET_RAW_VER((IPV4Hdr *)(pkt + PPP_HEADER_LEN)) == 4) {
DecodeIPV4(tv, dtv, p, pkt + PPP_HEADER_LEN, len - PPP_HEADER_LEN, pq);
}
break;
case PPP_IP:
if(len < (PPP_HEADER_LEN + IPV4_HEADER_LEN)) {
ENGINE_SET_EVENT(p,PPPIPV4_PKT_TOO_SMALL);
return;
}
DecodeIPV4(tv, dtv, p, pkt + PPP_HEADER_LEN, len - PPP_HEADER_LEN, pq);
break;
/* PPP IPv6 was not tested */
case PPP_IPV6:
if(len < (PPP_HEADER_LEN + IPV6_HEADER_LEN)) {
ENGINE_SET_EVENT(p,PPPIPV6_PKT_TOO_SMALL);
return;
}
DecodeIPV6(tv, dtv, p, pkt + PPP_HEADER_LEN, len - PPP_HEADER_LEN, pq);
break;
default:
SCLogDebug("unknown PPP protocol: %" PRIx32 "",ntohs(p->ppph->protocol));
ENGINE_SET_EVENT(p,PPP_WRONG_TYPE);

@ -48,7 +48,7 @@ void DecodeRaw(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, u
SCPerfCounterIncr(dtv->counter_raw, tv->sc_perf_pca);
/* If it is ipv4 or ipv6 it should at least be the size of ipv4 */
if (len < IPV4_HEADER_LEN) {
if (unlikely(len < IPV4_HEADER_LEN)) {
ENGINE_SET_EVENT(p,IPV4_PKT_TOO_SMALL);
return;
}

@ -40,13 +40,13 @@ void DecodeSll(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, u
{
SCPerfCounterIncr(dtv->counter_sll, tv->sc_perf_pca);
if (len < SLL_HEADER_LEN) {
if (unlikely(len < SLL_HEADER_LEN)) {
ENGINE_SET_EVENT(p,SLL_PKT_TOO_SMALL);
return;
}
SllHdr *sllh = (SllHdr *)pkt;
if (sllh == NULL)
if (unlikely(sllh == NULL))
return;
SCLogDebug("p %p pkt %p sll_protocol %04x", p, pkt, ntohs(sllh->sll_protocol));

@ -63,7 +63,7 @@ static int DecodeTCPOptions(Packet *p, uint8_t *pkt, uint16_t len)
/* we already know that the total options len is valid,
* so here the len of the specific option must be bad.
* Also check for invalid lengths 0 and 1. */
if (*(pkt+1) > plen || *(pkt+1) < 2) {
if (unlikely(*(pkt+1) > plen || *(pkt+1) < 2)) {
ENGINE_SET_EVENT(p,TCP_OPT_INVALID_LEN);
return -1;
}

@ -42,19 +42,19 @@
static int DecodeUDPPacket(ThreadVars *t, Packet *p, uint8_t *pkt, uint16_t len)
{
if (len < UDP_HEADER_LEN) {
if (unlikely(len < UDP_HEADER_LEN)) {
ENGINE_SET_EVENT(p, UDP_HLEN_TOO_SMALL);
return -1;
}
p->udph = (UDPHdr *)pkt;
if (len < UDP_GET_LEN(p)) {
if (unlikely(len < UDP_GET_LEN(p))) {
ENGINE_SET_EVENT(p, UDP_PKT_TOO_SMALL);
return -1;
}
if (len != UDP_GET_LEN(p)) {
if (unlikely(len != UDP_GET_LEN(p))) {
ENGINE_SET_EVENT(p, UDP_HLEN_INVALID);
return -1;
}
@ -74,7 +74,7 @@ void DecodeUDP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, u
{
SCPerfCounterIncr(dtv->counter_udp, tv->sc_perf_pca);
if (DecodeUDPPacket(tv, p,pkt,len) < 0) {
if (unlikely(DecodeUDPPacket(tv, p,pkt,len) < 0)) {
p->udph = NULL;
return;
}
@ -82,7 +82,7 @@ void DecodeUDP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, u
SCLogDebug("UDP sp: %" PRIu32 " -> dp: %" PRIu32 " - HLEN: %" PRIu32 " LEN: %" PRIu32 "",
UDP_GET_SRC_PORT(p), UDP_GET_DST_PORT(p), UDP_HEADER_LEN, p->payload_len);
if (DecodeTeredo(tv, dtv, p, p->payload, p->payload_len, pq) == 1) {
if (unlikely(DecodeTeredo(tv, dtv, p, p->payload, p->payload_len, pq) == 1)) {
/* Here we have a Teredo packet and don't need to handle app
* layer */
FlowHandlePacket(tv, p);
@ -93,7 +93,7 @@ void DecodeUDP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, u
FlowHandlePacket(tv, p);
/* handle the app layer part of the UDP packet payload */
if (p->flow != NULL) {
if (unlikely(p->flow != NULL)) {
AppLayerHandleUdp(&dtv->udp_dp_ctx, p->flow, p);
}

@ -168,7 +168,7 @@ Packet *PacketGetFromQueueOrAlloc(void)
*/
inline int PacketCopyDataOffset(Packet *p, int offset, uint8_t *data, int datalen)
{
if (offset + datalen > MAX_PAYLOAD_SIZE) {
if (unlikely(offset + datalen > MAX_PAYLOAD_SIZE)) {
/* too big */
return -1;
}
@ -181,7 +181,7 @@ inline int PacketCopyDataOffset(Packet *p, int offset, uint8_t *data, int datale
} else {
/* here we need a dynamic allocation */
p->ext_pkt = SCMalloc(MAX_PAYLOAD_SIZE);
if (p->ext_pkt == NULL) {
if (unlikely(p->ext_pkt == NULL)) {
SET_PKT_LEN(p, 0);
return -1;
}
@ -225,7 +225,7 @@ Packet *PacketPseudoPktSetup(Packet *parent, uint8_t *pkt, uint16_t len, uint8_t
/* get us a packet */
Packet *p = PacketGetFromQueueOrAlloc();
if (p == NULL) {
if (unlikely(p == NULL)) {
SCReturnPtr(NULL, "Packet");
}
@ -279,7 +279,7 @@ Packet *PacketDefragPktSetup(Packet *parent, uint8_t *pkt, uint16_t len, uint8_t
/* get us a packet */
Packet *p = PacketGetFromQueueOrAlloc();
if (p == NULL) {
if (unlikely(p == NULL)) {
SCReturnPtr(NULL, "Packet");
}
@ -454,7 +454,7 @@ DecodeThreadVars *DecodeThreadVarsAlloc()
inline int PacketSetData(Packet *p, uint8_t *pktdata, int pktlen)
{
SET_PKT_LEN(p, (size_t)pktlen);
if (!pktdata) {
if (unlikely(!pktdata)) {
return -1;
}
p->ext_pkt = pktdata;

@ -4763,23 +4763,23 @@ int StreamTcpGetFlowState(void *s)
SCEnter();
TcpSession *ssn = (TcpSession *)s;
if (ssn == NULL) {
if (unlikely(ssn == NULL)) {
SCReturnInt(FLOW_STATE_CLOSED);
}
/* sorted most likely to least likely */
switch(ssn->state) {
case TCP_NONE:
case TCP_SYN_SENT:
case TCP_SYN_RECV:
case TCP_LISTEN:
SCReturnInt(FLOW_STATE_NEW);
case TCP_ESTABLISHED:
case TCP_FIN_WAIT1:
case TCP_FIN_WAIT2:
case TCP_CLOSING:
case TCP_CLOSE_WAIT:
SCReturnInt(FLOW_STATE_ESTABLISHED);
case TCP_NONE:
case TCP_SYN_SENT:
case TCP_SYN_RECV:
case TCP_LISTEN:
SCReturnInt(FLOW_STATE_NEW);
case TCP_LAST_ACK:
case TCP_TIME_WAIT:
case TCP_CLOSED:

Loading…
Cancel
Save