Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tunnel/v8 #10597

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 19 additions & 16 deletions src/decode.c
Original file line number Diff line number Diff line change
Expand Up @@ -335,13 +335,15 @@ Packet *PacketTunnelPktSetup(ThreadVars *tv, DecodeThreadVars *dtv, Packet *pare
p->livedev = parent->livedev;

/* set the root ptr to the lowest layer */
if (parent->root != NULL)
if (parent->root != NULL) {
p->root = parent->root;
else
BUG_ON(parent->ttype != PacketTunnelChild);
} else {
p->root = parent;

parent->ttype = PacketTunnelRoot;
}
/* tell new packet it's part of a tunnel */
SET_TUNNEL_PKT(p);
p->ttype = PacketTunnelChild;

ret = DecodeTunnel(tv, dtv, p, GET_PKT_DATA(p),
GET_PKT_LEN(p), proto);
Expand All @@ -351,18 +353,15 @@ Packet *PacketTunnelPktSetup(ThreadVars *tv, DecodeThreadVars *dtv, Packet *pare
{
/* Not a (valid) tunnel packet */
SCLogDebug("tunnel packet is invalid");

p->root = NULL;
UNSET_TUNNEL_PKT(p);
TmqhOutputPacketpool(tv, p);
SCReturnPtr(NULL, "Packet");
}


/* tell parent packet it's part of a tunnel */
SET_TUNNEL_PKT(parent);

/* increment tunnel packet refcnt in the root packet */
/* Update tunnel settings in parent */
if (parent->root == NULL) {
parent->ttype = PacketTunnelRoot;
}
TUNNEL_INCR_PKT_TPR(p);

/* disable payload (not packet) inspection on the parent, as the payload
Expand Down Expand Up @@ -397,10 +396,15 @@ Packet *PacketDefragPktSetup(Packet *parent, const uint8_t *pkt, uint32_t len, u
}

/* set the root ptr to the lowest layer */
if (parent->root != NULL)
if (parent->root != NULL) {
p->root = parent->root;
else
BUG_ON(parent->ttype != PacketTunnelChild);
} else {
p->root = parent;
// we set parent->ttype later
}
/* tell new packet it's part of a tunnel */
p->ttype = PacketTunnelChild;

/* copy packet and set length, proto */
if (pkt && len) {
Expand All @@ -410,8 +414,6 @@ Packet *PacketDefragPktSetup(Packet *parent, const uint8_t *pkt, uint32_t len, u
p->ts = parent->ts;
p->datalink = DLT_RAW;
p->tenant_id = parent->tenant_id;
/* tell new packet it's part of a tunnel */
SET_TUNNEL_PKT(p);
memcpy(&p->vlan_id[0], &parent->vlan_id[0], sizeof(p->vlan_id));
p->vlan_idx = parent->vlan_idx;
p->livedev = parent->livedev;
Expand All @@ -426,7 +428,8 @@ Packet *PacketDefragPktSetup(Packet *parent, const uint8_t *pkt, uint32_t len, u
void PacketDefragPktSetupParent(Packet *parent)
{
/* tell parent packet it's part of a tunnel */
SET_TUNNEL_PKT(parent);
if (parent->ttype == PacketTunnelNone)
parent->ttype = PacketTunnelRoot;

/* increment tunnel packet refcnt in the root packet */
TUNNEL_INCR_PKT_TPR(parent);
Expand Down
95 changes: 68 additions & 27 deletions src/decode.h
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,12 @@ enum PacketDropReason {
PKT_DROP_REASON_MAX,
};

enum PacketTunnelType {
PacketTunnelNone,
PacketTunnelRoot,
PacketTunnelChild,
};

/* forward declaration since Packet struct definition requires this */
struct PacketQueue_;

Expand Down Expand Up @@ -472,6 +478,9 @@ typedef struct Packet_
* hash size still */
uint32_t flow_hash;

/* tunnel type: none, root or child */
enum PacketTunnelType ttype;

SCTime_t ts;

union {
Expand Down Expand Up @@ -618,6 +627,9 @@ typedef struct Packet_
/* enum PacketDropReason::PKT_DROP_REASON_* as uint8_t for compactness */
uint8_t drop_reason;

/** has verdict on this tunneled packet been issued? */
bool tunnel_verdicted;

/* tunnel/encapsulation handling */
struct Packet_ *root; /* in case of tunnel this is a ptr
* to the 'real' packet, the one we
Expand Down Expand Up @@ -646,8 +658,8 @@ typedef struct Packet_
/** lock to protect access to:
* - tunnel_rtv_cnt
* - tunnel_tpr_cnt
* - nfq_v.mark
* - flags
* - tunnel_verdicted
* - nfq_v.mark (if p->ttype != PacketTunnelNone)
*/
SCSpinlock tunnel_lock;
} persistent;
Expand Down Expand Up @@ -796,13 +808,14 @@ static inline void TUNNEL_INCR_PKT_TPR(Packet *p)
#define TUNNEL_PKT_RTV(p) ((p)->root ? (p)->root->tunnel_rtv_cnt : (p)->tunnel_rtv_cnt)
#define TUNNEL_PKT_TPR(p) ((p)->root ? (p)->root->tunnel_tpr_cnt : (p)->tunnel_tpr_cnt)

#define IS_TUNNEL_PKT(p) (((p)->flags & PKT_TUNNEL))
#define SET_TUNNEL_PKT(p) ((p)->flags |= PKT_TUNNEL)
#define UNSET_TUNNEL_PKT(p) ((p)->flags &= ~PKT_TUNNEL)
#define IS_TUNNEL_ROOT_PKT(p) (IS_TUNNEL_PKT(p) && (p)->root == NULL)

#define IS_TUNNEL_PKT_VERDICTED(p) (((p)->flags & PKT_TUNNEL_VERDICTED))
#define SET_TUNNEL_PKT_VERDICTED(p) ((p)->flags |= PKT_TUNNEL_VERDICTED)
static inline bool PacketTunnelIsVerdicted(const Packet *p)
{
return p->tunnel_verdicted;
}
static inline void PacketTunnelSetVerdicted(Packet *p)
{
p->tunnel_verdicted = true;
}

enum DecodeTunnelProto {
DECODE_TUNNEL_ETHERNET,
Expand Down Expand Up @@ -1008,14 +1021,14 @@ void DecodeUnregisterCounters(void);
/** Packet is modified by the stream engine, we need to recalc the csum and \
reinject/replace */
#define PKT_STREAM_MODIFIED BIT_U32(10)
/** Packet mark is modified */
#define PKT_MARK_MODIFIED BIT_U32(11)

// vacancy
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shift here as well?


/** Exclude packet from pcap logging as it's part of a stream that has reassembly \
depth reached. */
#define PKT_STREAM_NOPCAPLOG BIT_U32(12)

#define PKT_TUNNEL BIT_U32(13)
#define PKT_TUNNEL_VERDICTED BIT_U32(14)
// vacancy 2x

/** Packet checksum is not computed (TX packet for example) */
#define PKT_IGNORE_CHECKSUM BIT_U32(15)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't all the defines be shifted by two?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not shifting to keep flags stable. This mostly helps in debugging reported core dumps.

Expand Down Expand Up @@ -1091,6 +1104,46 @@ static inline void DecodeSetNoPacketInspectionFlag(Packet *p)
p->flags |= PKT_NOPACKET_INSPECTION;
}

static inline bool PacketIsTunnelRoot(const Packet *p)
{
return (p->ttype == PacketTunnelRoot);
}

static inline bool PacketIsTunnelChild(const Packet *p)
{
return (p->ttype == PacketTunnelChild);
}

static inline bool PacketIsTunnel(const Packet *p)
{
return (p->ttype != PacketTunnelNone);
}

static inline bool PacketIsNotTunnel(const Packet *p)
{
return (p->ttype == PacketTunnelNone);
}

static inline bool VerdictTunnelPacketInternal(const Packet *p)
{
const uint16_t outstanding = TUNNEL_PKT_TPR(p) - TUNNEL_PKT_RTV(p);
SCLogDebug("tunnel: outstanding %u", outstanding);

/* if there are packets outstanding, we won't verdict this one */
if (PacketIsTunnelRoot(p) && !PacketTunnelIsVerdicted(p) && !outstanding) {
SCLogDebug("root %p: verdict", p);
return true;

} else if (PacketIsTunnelChild(p) && outstanding == 1 && p->root &&
PacketTunnelIsVerdicted(p->root)) {
SCLogDebug("tunnel %p: verdict", p);
return true;

} else {
return false;
}
}

/** \brief return true if *this* packet needs to trigger a verdict.
*
* If we have the root packet, and we have none outstanding,
Expand All @@ -1103,22 +1156,10 @@ static inline void DecodeSetNoPacketInspectionFlag(Packet *p)
*/
static inline bool VerdictTunnelPacket(Packet *p)
{
bool verdict = true;
bool verdict;
SCSpinlock *lock = p->root ? &p->root->persistent.tunnel_lock : &p->persistent.tunnel_lock;
SCSpinLock(lock);
const uint16_t outstanding = TUNNEL_PKT_TPR(p) - TUNNEL_PKT_RTV(p);
SCLogDebug("tunnel: outstanding %u", outstanding);

/* if there are packets outstanding, we won't verdict this one */
if (IS_TUNNEL_ROOT_PKT(p) && !IS_TUNNEL_PKT_VERDICTED(p) && !outstanding) {
// verdict
SCLogDebug("root %p: verdict", p);
} else if (!IS_TUNNEL_ROOT_PKT(p) && outstanding == 1 && p->root && IS_TUNNEL_PKT_VERDICTED(p->root)) {
// verdict
SCLogDebug("tunnel %p: verdict", p);
} else {
verdict = false;
}
verdict = VerdictTunnelPacketInternal(p);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

declare variable here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess I don't like to declare a var inside a lock, then use it outside. It's a matter of style I think, I don't think it has practical effect

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, the comment was based on the experience from the previous PRs.

SCSpinUnlock(lock);
return verdict;
}
Expand Down
12 changes: 3 additions & 9 deletions src/defrag.c
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,6 @@ Defrag4Reassemble(ThreadVars *tv, DefragTracker *tracker, Packet *p)
}
PKT_SET_SRC(rp, PKT_SRC_DEFRAG);
rp->flags |= PKT_REBUILT_FRAGMENT;
rp->recursion_level = p->recursion_level;

int fragmentable_offset = 0;
uint16_t fragmentable_len = 0;
Expand Down Expand Up @@ -430,6 +429,7 @@ Defrag6Reassemble(ThreadVars *tv, DefragTracker *tracker, Packet *p)
goto error_remove_tracker;
}
PKT_SET_SRC(rp, PKT_SRC_DEFRAG);
rp->flags |= PKT_REBUILT_FRAGMENT;

uint16_t unfragmentable_len = 0;
int fragmentable_offset = 0;
Expand Down Expand Up @@ -873,10 +873,7 @@ DefragInsertFrag(ThreadVars *tv, DecodeThreadVars *dtv, DefragTracker *tracker,
r = Defrag4Reassemble(tv, tracker, p);
if (r != NULL && tv != NULL && dtv != NULL) {
StatsIncr(tv, dtv->counter_defrag_ipv4_reassembled);
if (DecodeIPV4(tv, dtv, r, (void *)r->ip4h,
IPV4_GET_IPLEN(r)) != TM_ECODE_OK) {

UNSET_TUNNEL_PKT(r);
if (DecodeIPV4(tv, dtv, r, (void *)r->ip4h, IPV4_GET_IPLEN(r)) != TM_ECODE_OK) {
r->root = NULL;
TmqhOutputPacketpool(tv, r);
r = NULL;
Expand All @@ -890,10 +887,7 @@ DefragInsertFrag(ThreadVars *tv, DecodeThreadVars *dtv, DefragTracker *tracker,
if (r != NULL && tv != NULL && dtv != NULL) {
StatsIncr(tv, dtv->counter_defrag_ipv6_reassembled);
if (DecodeIPV6(tv, dtv, r, (uint8_t *)r->ip6h,
IPV6_GET_PLEN(r) + IPV6_HEADER_LEN)
!= TM_ECODE_OK) {

UNSET_TUNNEL_PKT(r);
IPV6_GET_PLEN(r) + IPV6_HEADER_LEN) != TM_ECODE_OK) {
r->root = NULL;
TmqhOutputPacketpool(tv, r);
r = NULL;
Expand Down
11 changes: 8 additions & 3 deletions src/detect-mark.c
Original file line number Diff line number Diff line change
Expand Up @@ -228,11 +228,16 @@ static int DetectMarkPacket(DetectEngineThreadCtx *det_ctx, Packet *p,
#ifdef NFQ
const DetectMarkData *nf_data = (const DetectMarkData *)ctx;
if (nf_data->mask) {
if (!(IS_TUNNEL_PKT(p))) {
if (PacketIsNotTunnel(p)) {
/* for a non-tunnel packet we don't need a lock,
* and if we're here we can't turn into a tunnel
* packet anymore. */

/* coverity[missing_lock] */
p->nfq_v.mark = (nf_data->mark & nf_data->mask)
| (p->nfq_v.mark & ~(nf_data->mask));
p->flags |= PKT_MARK_MODIFIED;
/* coverity[missing_lock] */
p->nfq_v.mark_modified = true;
} else {
/* real tunnels may have multiple flows inside them, so marking
* might 'mark' too much. Rebuilt packets from IP fragments
Expand All @@ -242,7 +247,7 @@ static int DetectMarkPacket(DetectEngineThreadCtx *det_ctx, Packet *p,
SCSpinLock(&tp->persistent.tunnel_lock);
tp->nfq_v.mark = (nf_data->mark & nf_data->mask)
| (tp->nfq_v.mark & ~(nf_data->mask));
tp->flags |= PKT_MARK_MODIFIED;
tp->nfq_v.mark_modified = true;
SCSpinUnlock(&tp->persistent.tunnel_lock);
}
}
Expand Down
10 changes: 5 additions & 5 deletions src/log-pcap.c
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ static bool PcapLogCondition(ThreadVars *tv, void *thread_data, const Packet *p)
return false;
}

if (IS_TUNNEL_PKT(p) && !IS_TUNNEL_ROOT_PKT(p)) {
if (p->ttype == PacketTunnelChild) {
return false;
}
return true;
Expand Down Expand Up @@ -379,7 +379,7 @@ static int PcapLogOpenHandles(PcapLogData *pl, const Packet *p)
PCAPLOG_PROFILE_START;

int datalink = p->datalink;
if (IS_TUNNEL_PKT(p) && !IS_TUNNEL_ROOT_PKT(p)) {
if (p->ttype == PacketTunnelChild) {
Packet *real_p = p->root;
datalink = real_p->datalink;
}
Expand Down Expand Up @@ -588,7 +588,7 @@ static int PcapLog (ThreadVars *t, void *thread_data, const Packet *p)
pl->pkt_cnt++;
pl->h->ts.tv_sec = SCTIME_SECS(p->ts);
pl->h->ts.tv_usec = SCTIME_USECS(p->ts);
if (IS_TUNNEL_PKT(p) && !IS_TUNNEL_ROOT_PKT(p)) {
if (p->ttype == PacketTunnelChild) {
rp = p->root;
pl->h->caplen = GET_PKT_LEN(rp);
pl->h->len = GET_PKT_LEN(rp);
Expand Down Expand Up @@ -666,7 +666,7 @@ static int PcapLog (ThreadVars *t, void *thread_data, const Packet *p)
/* PcapLogDumpSegment has written over the PcapLogData variables so need to update */
pl->h->ts.tv_sec = SCTIME_SECS(p->ts);
pl->h->ts.tv_usec = SCTIME_USECS(p->ts);
if (IS_TUNNEL_PKT(p) && !IS_TUNNEL_ROOT_PKT(p)) {
if (p->ttype == PacketTunnelChild) {
rp = p->root;
pl->h->caplen = GET_PKT_LEN(rp);
pl->h->len = GET_PKT_LEN(rp);
Expand All @@ -679,7 +679,7 @@ static int PcapLog (ThreadVars *t, void *thread_data, const Packet *p)
}
}

if (IS_TUNNEL_PKT(p) && !IS_TUNNEL_ROOT_PKT(p)) {
if (p->ttype == PacketTunnelChild) {
rp = p->root;
#ifdef HAVE_LIBLZ4
ret = PcapWrite(pl, comp, GET_PKT_DATA(rp), len);
Expand Down
2 changes: 1 addition & 1 deletion src/output-json-alert.c
Original file line number Diff line number Diff line change
Expand Up @@ -562,7 +562,7 @@ static int AlertJson(ThreadVars *tv, JsonAlertLogThread *aft, const Packet *p)
/* alert */
AlertJsonHeader(json_output_ctx, p, pa, jb, json_output_ctx->flags, &addr, xff_buffer);

if (IS_TUNNEL_PKT(p)) {
if (PacketIsTunnel(p)) {
AlertJsonTunnel(p, jb);
}

Expand Down
2 changes: 2 additions & 0 deletions src/packet.c
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ void PacketReinit(Packet *p)
p->vlan_id[0] = 0;
p->vlan_id[1] = 0;
p->vlan_idx = 0;
p->ttype = PacketTunnelNone;
SCTIME_INIT(p->ts);
p->datalink = 0;
p->drop_reason = 0;
Expand Down Expand Up @@ -157,6 +158,7 @@ void PacketReinit(Packet *p)
AppLayerDecoderEventsResetEvents(p->app_layer_events);
p->next = NULL;
p->prev = NULL;
p->tunnel_verdicted = false;
p->root = NULL;
p->livedev = NULL;
PACKET_RESET_CHECKSUMS(p);
Expand Down
2 changes: 1 addition & 1 deletion src/respond-reject.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ static TmEcode RespondRejectFunc(ThreadVars *tv, Packet *p, void *data)
return TM_ECODE_OK;
}

if (IS_TUNNEL_PKT(p)) {
if (PacketIsTunnel(p)) {
return TM_ECODE_OK;
}

Expand Down
Loading
Loading