Commit 6e45749b authored by yonghong-song's avatar yonghong-song Committed by GitHub

Merge pull request #1285 from pchaigno/track-external-pointers-maps

Trace external pointers through maps
parents 6b511bd9 e67cb561
...@@ -55,11 +55,9 @@ int kretprobe__tcp_v4_connect(struct pt_regs *ctx) ...@@ -55,11 +55,9 @@ int kretprobe__tcp_v4_connect(struct pt_regs *ctx)
// pull in details // pull in details
struct sock *skp = *skpp; struct sock *skp = *skpp;
u32 saddr = 0, daddr = 0; u32 saddr = skp->__sk_common.skc_rcv_saddr;
u16 dport = 0; u32 daddr = skp->__sk_common.skc_daddr;
bpf_probe_read(&saddr, sizeof(saddr), &skp->__sk_common.skc_rcv_saddr); u16 dport = skp->__sk_common.skc_dport;
bpf_probe_read(&daddr, sizeof(daddr), &skp->__sk_common.skc_daddr);
bpf_probe_read(&dport, sizeof(dport), &skp->__sk_common.skc_dport);
// output // output
bpf_trace_printk("trace_tcp4connect %x %x %d\\n", saddr, daddr, ntohs(dport)); bpf_trace_printk("trace_tcp4connect %x %x %d\\n", saddr, daddr, ntohs(dport));
......
...@@ -108,7 +108,29 @@ class ProbeSetter : public RecursiveASTVisitor<ProbeSetter> { ...@@ -108,7 +108,29 @@ class ProbeSetter : public RecursiveASTVisitor<ProbeSetter> {
set<Decl *> *ptregs_; set<Decl *> *ptregs_;
}; };
ProbeVisitor::ProbeVisitor(ASTContext &C, Rewriter &rewriter) : C(C), rewriter_(rewriter) {} MapVisitor::MapVisitor(set<Decl *> &m) : m_(m) {}
bool MapVisitor::VisitCallExpr(CallExpr *Call) {
if (MemberExpr *Memb = dyn_cast<MemberExpr>(Call->getCallee()->IgnoreImplicit())) {
StringRef memb_name = Memb->getMemberDecl()->getName();
if (DeclRefExpr *Ref = dyn_cast<DeclRefExpr>(Memb->getBase())) {
if (SectionAttr *A = Ref->getDecl()->getAttr<SectionAttr>()) {
if (!A->getName().startswith("maps"))
return true;
if (memb_name == "update" || memb_name == "insert") {
if (ProbeChecker(Call->getArg(1), ptregs_).needs_probe()) {
m_.insert(Ref->getDecl());
}
}
}
}
}
return true;
}
ProbeVisitor::ProbeVisitor(ASTContext &C, Rewriter &rewriter, set<Decl *> &m) :
C(C), rewriter_(rewriter), m_(m) {}
bool ProbeVisitor::VisitVarDecl(VarDecl *Decl) { bool ProbeVisitor::VisitVarDecl(VarDecl *Decl) {
if (Expr *E = Decl->getInit()) { if (Expr *E = Decl->getInit()) {
...@@ -141,6 +163,25 @@ bool ProbeVisitor::VisitBinaryOperator(BinaryOperator *E) { ...@@ -141,6 +163,25 @@ bool ProbeVisitor::VisitBinaryOperator(BinaryOperator *E) {
if (ProbeChecker(E->getRHS(), ptregs_).is_transitive()) { if (ProbeChecker(E->getRHS(), ptregs_).is_transitive()) {
ProbeSetter setter(&ptregs_); ProbeSetter setter(&ptregs_);
setter.TraverseStmt(E->getLHS()); setter.TraverseStmt(E->getLHS());
} else if (E->isAssignmentOp() && E->getRHS()->getStmtClass() == Stmt::CallExprClass) {
CallExpr *Call = dyn_cast<CallExpr>(E->getRHS());
if (MemberExpr *Memb = dyn_cast<MemberExpr>(Call->getCallee()->IgnoreImplicit())) {
StringRef memb_name = Memb->getMemberDecl()->getName();
if (DeclRefExpr *Ref = dyn_cast<DeclRefExpr>(Memb->getBase())) {
if (SectionAttr *A = Ref->getDecl()->getAttr<SectionAttr>()) {
if (!A->getName().startswith("maps"))
return true;
if (memb_name == "lookup" || memb_name == "lookup_or_init") {
if (m_.find(Ref->getDecl()) != m_.end()) {
// Retrieved an external pointer from a map, mark LHS as external pointer.
ProbeSetter setter(&ptregs_);
setter.TraverseStmt(E->getLHS());
}
}
}
}
}
} }
return true; return true;
} }
...@@ -752,30 +793,49 @@ bool BTypeVisitor::VisitVarDecl(VarDecl *Decl) { ...@@ -752,30 +793,49 @@ bool BTypeVisitor::VisitVarDecl(VarDecl *Decl) {
return true; return true;
} }
BTypeConsumer::BTypeConsumer(ASTContext &C, BFrontendAction &fe) : visitor_(C, fe) {} // First traversal of AST to retrieve maps with external pointers.
BTypeConsumer::BTypeConsumer(ASTContext &C, BFrontendAction &fe,
Rewriter &rewriter, set<Decl *> &m) :
map_visitor_(m), btype_visitor_(C, fe), probe_visitor_(C, rewriter, m) {}
bool BTypeConsumer::HandleTopLevelDecl(DeclGroupRef Group) { bool BTypeConsumer::HandleTopLevelDecl(DeclGroupRef Group) {
for (auto D : Group) for (auto D : Group) {
visitor_.TraverseDecl(D); if (FunctionDecl *F = dyn_cast<FunctionDecl>(D)) {
if (F->isExternallyVisible() && F->hasBody()) {
for (auto arg : F->parameters()) {
if (arg != F->getParamDecl(0) && !arg->getType()->isFundamentalType()) {
map_visitor_.set_ptreg(arg);
}
}
map_visitor_.TraverseDecl(D);
}
}
}
return true; return true;
} }
ProbeConsumer::ProbeConsumer(ASTContext &C, Rewriter &rewriter) void BTypeConsumer::HandleTranslationUnit(ASTContext &Context) {
: visitor_(C, rewriter) {} DeclContext::decl_iterator it;
DeclContext *DC = TranslationUnitDecl::castToDeclContext(Context.getTranslationUnitDecl());
bool ProbeConsumer::HandleTopLevelDecl(DeclGroupRef Group) { /**
for (auto D : Group) { * ProbeVisitor's traversal runs after an entire translation unit has been parsed.
* to make sure maps with external pointers have been identified.
*/
for (it = DC->decls_begin(); it != DC->decls_end(); it++) {
Decl *D = *it;
if (FunctionDecl *F = dyn_cast<FunctionDecl>(D)) { if (FunctionDecl *F = dyn_cast<FunctionDecl>(D)) {
if (F->isExternallyVisible() && F->hasBody()) { if (F->isExternallyVisible() && F->hasBody()) {
for (auto arg : F->parameters()) { for (auto arg : F->parameters()) {
if (arg != F->getParamDecl(0) && !arg->getType()->isFundamentalType()) if (arg != F->getParamDecl(0) && !arg->getType()->isFundamentalType())
visitor_.set_ptreg(arg); probe_visitor_.set_ptreg(arg);
} }
visitor_.TraverseDecl(D); probe_visitor_.TraverseDecl(D);
} }
} }
btype_visitor_.TraverseDecl(D);
} }
return true;
} }
BFrontendAction::BFrontendAction(llvm::raw_ostream &os, unsigned flags, BFrontendAction::BFrontendAction(llvm::raw_ostream &os, unsigned flags,
...@@ -810,8 +870,7 @@ void BFrontendAction::EndSourceFileAction() { ...@@ -810,8 +870,7 @@ void BFrontendAction::EndSourceFileAction() {
unique_ptr<ASTConsumer> BFrontendAction::CreateASTConsumer(CompilerInstance &Compiler, llvm::StringRef InFile) { unique_ptr<ASTConsumer> BFrontendAction::CreateASTConsumer(CompilerInstance &Compiler, llvm::StringRef InFile) {
rewriter_->setSourceMgr(Compiler.getSourceManager(), Compiler.getLangOpts()); rewriter_->setSourceMgr(Compiler.getSourceManager(), Compiler.getLangOpts());
vector<unique_ptr<ASTConsumer>> consumers; vector<unique_ptr<ASTConsumer>> consumers;
consumers.push_back(unique_ptr<ASTConsumer>(new ProbeConsumer(Compiler.getASTContext(), *rewriter_))); consumers.push_back(unique_ptr<ASTConsumer>(new BTypeConsumer(Compiler.getASTContext(), *this, *rewriter_, m_)));
consumers.push_back(unique_ptr<ASTConsumer>(new BTypeConsumer(Compiler.getASTContext(), *this)));
return unique_ptr<ASTConsumer>(new MultiplexConsumer(std::move(consumers))); return unique_ptr<ASTConsumer>(new MultiplexConsumer(std::move(consumers)));
} }
......
...@@ -42,6 +42,17 @@ namespace ebpf { ...@@ -42,6 +42,17 @@ namespace ebpf {
class BFrontendAction; class BFrontendAction;
class FuncSource; class FuncSource;
// Traces maps with external pointers as values.
class MapVisitor : public clang::RecursiveASTVisitor<MapVisitor> {
public:
explicit MapVisitor(std::set<clang::Decl *> &m);
bool VisitCallExpr(clang::CallExpr *Call);
void set_ptreg(clang::Decl *D) { ptregs_.insert(D); }
private:
std::set<clang::Decl *> &m_;
std::set<clang::Decl *> ptregs_;
};
// Type visitor and rewriter for B programs. // Type visitor and rewriter for B programs.
// It will look for B-specific features and rewrite them into a valid // It will look for B-specific features and rewrite them into a valid
// C program. As part of the processing, open the necessary BPF tables // C program. As part of the processing, open the necessary BPF tables
...@@ -77,7 +88,7 @@ class BTypeVisitor : public clang::RecursiveASTVisitor<BTypeVisitor> { ...@@ -77,7 +88,7 @@ class BTypeVisitor : public clang::RecursiveASTVisitor<BTypeVisitor> {
// Do a depth-first search to rewrite all pointers that need to be probed // Do a depth-first search to rewrite all pointers that need to be probed
class ProbeVisitor : public clang::RecursiveASTVisitor<ProbeVisitor> { class ProbeVisitor : public clang::RecursiveASTVisitor<ProbeVisitor> {
public: public:
explicit ProbeVisitor(clang::ASTContext &C, clang::Rewriter &rewriter); explicit ProbeVisitor(clang::ASTContext &C, clang::Rewriter &rewriter, std::set<clang::Decl *> &m);
bool VisitVarDecl(clang::VarDecl *Decl); bool VisitVarDecl(clang::VarDecl *Decl);
bool VisitCallExpr(clang::CallExpr *Call); bool VisitCallExpr(clang::CallExpr *Call);
bool VisitBinaryOperator(clang::BinaryOperator *E); bool VisitBinaryOperator(clang::BinaryOperator *E);
...@@ -94,24 +105,19 @@ class ProbeVisitor : public clang::RecursiveASTVisitor<ProbeVisitor> { ...@@ -94,24 +105,19 @@ class ProbeVisitor : public clang::RecursiveASTVisitor<ProbeVisitor> {
std::set<clang::Decl *> fn_visited_; std::set<clang::Decl *> fn_visited_;
std::set<clang::Expr *> memb_visited_; std::set<clang::Expr *> memb_visited_;
std::set<clang::Decl *> ptregs_; std::set<clang::Decl *> ptregs_;
std::set<clang::Decl *> &m_;
}; };
// A helper class to the frontend action, walks the decls // A helper class to the frontend action, walks the decls
class BTypeConsumer : public clang::ASTConsumer { class BTypeConsumer : public clang::ASTConsumer {
public: public:
explicit BTypeConsumer(clang::ASTContext &C, BFrontendAction &fe); explicit BTypeConsumer(clang::ASTContext &C, BFrontendAction &fe, clang::Rewriter &rewriter, std::set<clang::Decl *> &map);
bool HandleTopLevelDecl(clang::DeclGroupRef Group) override;
private:
BTypeVisitor visitor_;
};
// A helper class to the frontend action, walks the decls
class ProbeConsumer : public clang::ASTConsumer {
public:
ProbeConsumer(clang::ASTContext &C, clang::Rewriter &rewriter);
bool HandleTopLevelDecl(clang::DeclGroupRef Group) override; bool HandleTopLevelDecl(clang::DeclGroupRef Group) override;
void HandleTranslationUnit(clang::ASTContext &Context) override;
private: private:
ProbeVisitor visitor_; MapVisitor map_visitor_;
BTypeVisitor btype_visitor_;
ProbeVisitor probe_visitor_;
}; };
// Create a B program in 2 phases (everything else is normal C frontend): // Create a B program in 2 phases (everything else is normal C frontend):
...@@ -146,6 +152,7 @@ class BFrontendAction : public clang::ASTFrontendAction { ...@@ -146,6 +152,7 @@ class BFrontendAction : public clang::ASTFrontendAction {
std::map<std::string, clang::SourceRange> func_range_; std::map<std::string, clang::SourceRange> func_range_;
FuncSource &func_src_; FuncSource &func_src_;
std::string &mod_src_; std::string &mod_src_;
std::set<clang::Decl *> m_;
}; };
} // namespace visitor } // namespace visitor
...@@ -461,6 +461,36 @@ int process(struct xdp_md *ctx) { ...@@ -461,6 +461,36 @@ int process(struct xdp_md *ctx) {
t = b["act"] t = b["act"]
self.assertEquals(len(t), 32); self.assertEquals(len(t), 32);
def test_ext_ptr_maps(self):
bpf_text = """
#include <uapi/linux/ptrace.h>
#include <net/sock.h>
#include <bcc/proto.h>
BPF_HASH(currsock, u32, struct sock *);
int trace_entry(struct pt_regs *ctx, struct sock *sk,
struct sockaddr *uaddr, int addr_len) {
u32 pid = bpf_get_current_pid_tgid();
currsock.update(&pid, &sk);
return 0;
};
int trace_exit(struct pt_regs *ctx) {
u32 pid = bpf_get_current_pid_tgid();
struct sock **skpp;
skpp = currsock.lookup(&pid);
if (skpp) {
struct sock *skp = *skpp;
return skp->__sk_common.skc_dport;
}
return 0;
}
"""
b = BPF(text=bpf_text)
b.load_func("trace_entry", BPF.KPROBE)
b.load_func("trace_exit", BPF.KPROBE)
def test_bpf_dins_pkt_rewrite(self): def test_bpf_dins_pkt_rewrite(self):
text = """ text = """
#include <bcc/proto.h> #include <bcc/proto.h>
......
...@@ -86,15 +86,9 @@ int trace_completion(struct pt_regs *ctx) ...@@ -86,15 +86,9 @@ int trace_completion(struct pt_regs *ctx)
if (tsp == 0 || descp == 0) { if (tsp == 0 || descp == 0) {
return 0; // missed start return 0; // missed start
} }
// Note: descp is a value from map, so '&' can be done without struct irq_desc *desc = *descp;
// probe_read, but the next level irqaction * needs a probe read. struct irqaction *action = desc->action;
// Do these steps first after reading the map, otherwise some of these char *name = (char *)action->name;
// pointers may get pushed onto the stack and verifier will fail.
struct irqaction *action = 0;
bpf_probe_read(&action, sizeof(action), &(*descp)->action);
const char **namep = &action->name;
char *name = 0;
bpf_probe_read(&name, sizeof(name), namep);
delta = bpf_ktime_get_ns() - *tsp; delta = bpf_ktime_get_ns() - *tsp;
// store as sum or histogram // store as sum or histogram
......
...@@ -108,18 +108,15 @@ static int trace_connect_return(struct pt_regs *ctx, short ipver) ...@@ -108,18 +108,15 @@ static int trace_connect_return(struct pt_regs *ctx, short ipver)
// pull in details // pull in details
struct sock *skp = *skpp; struct sock *skp = *skpp;
u16 dport = 0; u16 dport = skp->__sk_common.skc_dport;
bpf_probe_read(&dport, sizeof(dport), &skp->__sk_common.skc_dport);
FILTER_PORT FILTER_PORT
if (ipver == 4) { if (ipver == 4) {
struct ipv4_data_t data4 = {.pid = pid, .ip = ipver}; struct ipv4_data_t data4 = {.pid = pid, .ip = ipver};
data4.ts_us = bpf_ktime_get_ns() / 1000; data4.ts_us = bpf_ktime_get_ns() / 1000;
bpf_probe_read(&data4.saddr, sizeof(u32), data4.saddr = skp->__sk_common.skc_rcv_saddr;
&skp->__sk_common.skc_rcv_saddr); data4.daddr = skp->__sk_common.skc_daddr;
bpf_probe_read(&data4.daddr, sizeof(u32),
&skp->__sk_common.skc_daddr);
data4.dport = ntohs(dport); data4.dport = ntohs(dport);
bpf_get_current_comm(&data4.task, sizeof(data4.task)); bpf_get_current_comm(&data4.task, sizeof(data4.task));
ipv4_events.perf_submit(ctx, &data4, sizeof(data4)); ipv4_events.perf_submit(ctx, &data4, sizeof(data4));
...@@ -128,9 +125,9 @@ static int trace_connect_return(struct pt_regs *ctx, short ipver) ...@@ -128,9 +125,9 @@ static int trace_connect_return(struct pt_regs *ctx, short ipver)
struct ipv6_data_t data6 = {.pid = pid, .ip = ipver}; struct ipv6_data_t data6 = {.pid = pid, .ip = ipver};
data6.ts_us = bpf_ktime_get_ns() / 1000; data6.ts_us = bpf_ktime_get_ns() / 1000;
bpf_probe_read(&data6.saddr, sizeof(data6.saddr), bpf_probe_read(&data6.saddr, sizeof(data6.saddr),
&skp->__sk_common.skc_v6_rcv_saddr.in6_u.u6_addr32); skp->__sk_common.skc_v6_rcv_saddr.in6_u.u6_addr32);
bpf_probe_read(&data6.daddr, sizeof(data6.daddr), bpf_probe_read(&data6.daddr, sizeof(data6.daddr),
&skp->__sk_common.skc_v6_daddr.in6_u.u6_addr32); skp->__sk_common.skc_v6_daddr.in6_u.u6_addr32);
data6.dport = ntohs(dport); data6.dport = ntohs(dport);
bpf_get_current_comm(&data6.task, sizeof(data6.task)); bpf_get_current_comm(&data6.task, sizeof(data6.task));
ipv6_events.perf_submit(ctx, &data6, sizeof(data6)); ipv6_events.perf_submit(ctx, &data6, sizeof(data6));
......
...@@ -107,20 +107,15 @@ BPF_HASH(connectsock, u64, struct sock *); ...@@ -107,20 +107,15 @@ BPF_HASH(connectsock, u64, struct sock *);
static int read_ipv4_tuple(struct ipv4_tuple_t *tuple, struct sock *skp) static int read_ipv4_tuple(struct ipv4_tuple_t *tuple, struct sock *skp)
{ {
u32 saddr = 0, daddr = 0, net_ns_inum = 0; u32 net_ns_inum = 0;
u16 sport = 0, dport = 0; u32 saddr = skp->__sk_common.skc_rcv_saddr;
possible_net_t skc_net; u32 daddr = skp->__sk_common.skc_daddr;
struct inet_sock *sockp = (struct inet_sock *)skp;
bpf_probe_read(&saddr, sizeof(saddr), &skp->__sk_common.skc_rcv_saddr); u16 sport = sockp->inet_sport;
bpf_probe_read(&daddr, sizeof(daddr), &skp->__sk_common.skc_daddr); u16 dport = skp->__sk_common.skc_dport;
bpf_probe_read(&sport, sizeof(sport),
&((struct inet_sock *)skp)->inet_sport);
bpf_probe_read(&dport, sizeof(dport), &skp->__sk_common.skc_dport);
#ifdef CONFIG_NET_NS #ifdef CONFIG_NET_NS
bpf_probe_read(&skc_net, sizeof(skc_net), &skp->__sk_common.skc_net); possible_net_t skc_net = skp->__sk_common.skc_net;
bpf_probe_read(&net_ns_inum, sizeof(net_ns_inum), &skc_net.net->ns.inum); bpf_probe_read(&net_ns_inum, sizeof(net_ns_inum), &skc_net.net->ns.inum);
#else
net_ns_inum = 0;
#endif #endif
##FILTER_NETNS## ##FILTER_NETNS##
...@@ -142,23 +137,18 @@ static int read_ipv4_tuple(struct ipv4_tuple_t *tuple, struct sock *skp) ...@@ -142,23 +137,18 @@ static int read_ipv4_tuple(struct ipv4_tuple_t *tuple, struct sock *skp)
static int read_ipv6_tuple(struct ipv6_tuple_t *tuple, struct sock *skp) static int read_ipv6_tuple(struct ipv6_tuple_t *tuple, struct sock *skp)
{ {
u32 net_ns_inum = 0; u32 net_ns_inum = 0;
u16 sport = 0, dport = 0;
unsigned __int128 saddr = 0, daddr = 0; unsigned __int128 saddr = 0, daddr = 0;
possible_net_t skc_net; struct inet_sock *sockp = (struct inet_sock *)skp;
u16 sport = sockp->inet_sport;
bpf_probe_read(&sport, sizeof(sport), u16 dport = skp->__sk_common.skc_dport;
&((struct inet_sock *)skp)->inet_sport);
bpf_probe_read(&dport, sizeof(dport), &skp->__sk_common.skc_dport);
bpf_probe_read(&saddr, sizeof(saddr),
&skp->__sk_common.skc_v6_rcv_saddr.in6_u.u6_addr32);
bpf_probe_read(&daddr, sizeof(daddr),
&skp->__sk_common.skc_v6_daddr.in6_u.u6_addr32);
#ifdef CONFIG_NET_NS #ifdef CONFIG_NET_NS
bpf_probe_read(&skc_net, sizeof(skc_net), &skp->__sk_common.skc_net); possible_net_t skc_net = skp->__sk_common.skc_net;
bpf_probe_read(&net_ns_inum, sizeof(net_ns_inum), &skc_net.net->ns.inum); bpf_probe_read(&net_ns_inum, sizeof(net_ns_inum), &skc_net.net->ns.inum);
#else
net_ns_inum = 0;
#endif #endif
bpf_probe_read(&saddr, sizeof(saddr),
skp->__sk_common.skc_v6_rcv_saddr.in6_u.u6_addr32);
bpf_probe_read(&daddr, sizeof(daddr),
skp->__sk_common.skc_v6_daddr.in6_u.u6_addr32);
##FILTER_NETNS## ##FILTER_NETNS##
...@@ -178,10 +168,7 @@ static int read_ipv6_tuple(struct ipv6_tuple_t *tuple, struct sock *skp) ...@@ -178,10 +168,7 @@ static int read_ipv6_tuple(struct ipv6_tuple_t *tuple, struct sock *skp)
static bool check_family(struct sock *sk, u16 expected_family) { static bool check_family(struct sock *sk, u16 expected_family) {
u64 zero = 0; u64 zero = 0;
u16 family = 0; u16 family = sk->__sk_common.skc_family;
bpf_probe_read(&family, sizeof(family), &sk->__sk_common.skc_family);
return family == expected_family; return family == expected_family;
} }
...@@ -279,15 +266,12 @@ int trace_connect_v6_return(struct pt_regs *ctx) ...@@ -279,15 +266,12 @@ int trace_connect_v6_return(struct pt_regs *ctx)
return 0; return 0;
} }
int trace_tcp_set_state_entry(struct pt_regs *ctx, struct sock *sk, int state) int trace_tcp_set_state_entry(struct pt_regs *ctx, struct sock *skp, int state)
{ {
if (state != TCP_ESTABLISHED && state != TCP_CLOSE) { if (state != TCP_ESTABLISHED && state != TCP_CLOSE) {
return 0; return 0;
} }
struct sock *skp;
bpf_probe_read(&skp, sizeof(struct sock *), &sk);
u8 ipver = 0; u8 ipver = 0;
if (check_family(skp, AF_INET)) { if (check_family(skp, AF_INET)) {
ipver = 4; ipver = 4;
...@@ -367,18 +351,13 @@ int trace_tcp_set_state_entry(struct pt_regs *ctx, struct sock *sk, int state) ...@@ -367,18 +351,13 @@ int trace_tcp_set_state_entry(struct pt_regs *ctx, struct sock *sk, int state)
return 0; return 0;
} }
int trace_close_entry(struct pt_regs *ctx, struct sock *sk) int trace_close_entry(struct pt_regs *ctx, struct sock *skp)
{ {
u64 pid = bpf_get_current_pid_tgid(); u64 pid = bpf_get_current_pid_tgid();
##FILTER_PID## ##FILTER_PID##
// pull in details u8 oldstate = skp->sk_state;
struct sock *skp;
bpf_probe_read(&skp, sizeof(struct sock *), &sk);
u8 oldstate = 0;
bpf_probe_read(&oldstate, sizeof(oldstate), (u8 *)&skp->sk_state);
// Don't generate close events for connections that were never // Don't generate close events for connections that were never
// established in the first place. // established in the first place.
if (oldstate == TCP_SYN_SENT || if (oldstate == TCP_SYN_SENT ||
...@@ -500,9 +479,9 @@ int trace_accept_return(struct pt_regs *ctx) ...@@ -500,9 +479,9 @@ int trace_accept_return(struct pt_regs *ctx)
evt6.ip = ipver; evt6.ip = ipver;
bpf_probe_read(&evt6.saddr, sizeof(evt6.saddr), bpf_probe_read(&evt6.saddr, sizeof(evt6.saddr),
&newsk->__sk_common.skc_v6_rcv_saddr.in6_u.u6_addr32); newsk->__sk_common.skc_v6_rcv_saddr.in6_u.u6_addr32);
bpf_probe_read(&evt6.daddr, sizeof(evt6.daddr), bpf_probe_read(&evt6.daddr, sizeof(evt6.daddr),
&newsk->__sk_common.skc_v6_daddr.in6_u.u6_addr32); newsk->__sk_common.skc_v6_daddr.in6_u.u6_addr32);
evt6.sport = lport; evt6.sport = lport;
evt6.dport = ntohs(dport); evt6.dport = ntohs(dport);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment