-
Notifications
You must be signed in to change notification settings - Fork 35
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
NETOBSERV-1996: in-kernel de-duplication #470
Changes from all commits
0736005
a03961b
68a9c67
7bbe7ff
e9818dd
c8ba1f6
5360bc8
3436484
d7de35a
1249501
7e072f4
6b89456
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -79,6 +79,23 @@ static inline void update_dns(additional_metrics *extra_metrics, pkt_info *pkt, | |
} | ||
} | ||
|
||
static inline void add_observed_intf(additional_metrics *value, u32 if_index, u8 direction) { | ||
if (value->nb_observed_intf < MAX_OBSERVED_INTERFACES) { | ||
for (u8 i = 0; i < value->nb_observed_intf; i++) { | ||
if (value->observed_intf[i].if_index == if_index && | ||
value->observed_intf[i].direction == direction) { | ||
return; | ||
} | ||
} | ||
value->observed_intf[value->nb_observed_intf].if_index = if_index; | ||
value->observed_intf[value->nb_observed_intf].direction = direction; | ||
value->nb_observed_intf++; | ||
jotak marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} else { | ||
increase_counter(OBSERVED_INTF_MISSED); | ||
BPF_PRINTK("observed interface missed (array capacity reached) for ifindex %d\n", if_index); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we need an else here and log a msg and probably updated a counter I assume the value of 4 is based on what we see today but depends on how often we come to else we might need to increase it. what happens when we hit the above condition is that a bad flow that we should drop or u can return error code in this function and do the print and counter update at the caller but we can't just be silent when this condition happens There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. right, +1 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think there's the same thing with MAX_NETWORK_EVENTS that we may silently ignore. I'll check to add that at the same time. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. network events I return error so that should be fine There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh I didn't notice the rolling increase here There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (anyway, I won't touch that in this PR, will focus just on observed_intf) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yeah that was by design newer events will overwrite older ones but as of now we can't get more than 3 events max per flow so we should be fine for now There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done here f2a7a94 |
||
} | ||
|
||
static inline int flow_monitor(struct __sk_buff *skb, u8 direction) { | ||
u32 filter_sampling = 0; | ||
|
||
|
@@ -110,13 +127,10 @@ static inline int flow_monitor(struct __sk_buff *skb, u8 direction) { | |
return TC_ACT_OK; | ||
} | ||
|
||
//Set extra fields | ||
id.if_index = skb->ifindex; | ||
id.direction = direction; | ||
|
||
// check if this packet need to be filtered if filtering feature is enabled | ||
if (is_filter_enabled()) { | ||
bool skip = check_and_do_flow_filtering(&id, pkt.flags, 0, eth_protocol, &filter_sampling); | ||
bool skip = check_and_do_flow_filtering(&id, pkt.flags, 0, eth_protocol, &filter_sampling, | ||
direction); | ||
if (filter_sampling == 0) { | ||
filter_sampling = sampling; | ||
} | ||
|
@@ -137,19 +151,47 @@ static inline int flow_monitor(struct __sk_buff *skb, u8 direction) { | |
} | ||
flow_metrics *aggregate_flow = (flow_metrics *)bpf_map_lookup_elem(&aggregated_flows, &id); | ||
if (aggregate_flow != NULL) { | ||
update_existing_flow(aggregate_flow, &pkt, len, filter_sampling); | ||
if (aggregate_flow->if_index_first_seen == skb->ifindex) { | ||
update_existing_flow(aggregate_flow, &pkt, len, filter_sampling); | ||
} else if (skb->ifindex != 0) { | ||
// Only add info that we've seen this interface | ||
additional_metrics *extra_metrics = | ||
(additional_metrics *)bpf_map_lookup_elem(&additional_flow_metrics, &id); | ||
if (extra_metrics != NULL) { | ||
add_observed_intf(extra_metrics, skb->ifindex, direction); | ||
} else { | ||
additional_metrics new_metrics = { | ||
.eth_protocol = eth_protocol, | ||
.start_mono_time_ts = pkt.current_ts, | ||
.end_mono_time_ts = pkt.current_ts, | ||
}; | ||
add_observed_intf(&new_metrics, skb->ifindex, direction); | ||
long ret = | ||
bpf_map_update_elem(&additional_flow_metrics, &id, &new_metrics, BPF_NOEXIST); | ||
if (ret == -EEXIST) { | ||
extra_metrics = | ||
(additional_metrics *)bpf_map_lookup_elem(&additional_flow_metrics, &id); | ||
if (extra_metrics != NULL) { | ||
add_observed_intf(extra_metrics, skb->ifindex, direction); | ||
} | ||
} else if (ret != 0 && trace_messages) { | ||
bpf_printk("error creating new observed_intf: %d\n", ret); | ||
} | ||
} | ||
} | ||
} else { | ||
// Key does not exist in the map, and will need to create a new entry. | ||
flow_metrics new_flow = { | ||
.packets = 1, | ||
.bytes = len, | ||
.eth_protocol = eth_protocol, | ||
.start_mono_time_ts = pkt.current_ts, | ||
.end_mono_time_ts = pkt.current_ts, | ||
.flags = pkt.flags, | ||
.dscp = pkt.dscp, | ||
.sampling = filter_sampling, | ||
}; | ||
flow_metrics new_flow; | ||
__builtin_memset(&new_flow, 0, sizeof(new_flow)); | ||
new_flow.if_index_first_seen = skb->ifindex; | ||
new_flow.direction_first_seen = direction; | ||
new_flow.packets = 1; | ||
new_flow.bytes = len; | ||
new_flow.eth_protocol = eth_protocol; | ||
new_flow.start_mono_time_ts = pkt.current_ts; | ||
new_flow.end_mono_time_ts = pkt.current_ts; | ||
new_flow.dscp = pkt.dscp; | ||
new_flow.sampling = filter_sampling; | ||
__builtin_memcpy(new_flow.dst_mac, eth->h_dest, ETH_ALEN); | ||
__builtin_memcpy(new_flow.src_mac, eth->h_source, ETH_ALEN); | ||
|
||
|
@@ -194,9 +236,6 @@ static inline int flow_monitor(struct __sk_buff *skb, u8 direction) { | |
|
||
// Update additional metrics (per-CPU map) | ||
if (pkt.dns_id != 0 || dns_errno != 0) { | ||
// hack on id will be removed with dedup-in-kernel work | ||
id.direction = 0; | ||
id.if_index = 0; | ||
additional_metrics *extra_metrics = | ||
(additional_metrics *)bpf_map_lookup_elem(&additional_flow_metrics, &id); | ||
if (extra_metrics != NULL) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should check
if_index
make sure its not 0There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm do you think I should also ignore setting
if_index_first_seen
toskb->ifindex
if it's 0 ?(in
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(idk in what cases it would be 0 and if it's something to handle in a special way)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added
else if (skb->ifindex != 0)
earlier in the code pathThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there are certian hooks that don't populate if_index u can see examples of that in the current code where we skip populating flow if
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok but here it's the tc hook ; maybe that's something not relevant now that other hooks use a different map? anyway it won't hurt to keep these checks, I guess...