Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Rocko Bonaparte
Mar 12, 2002

Every day is Friday!
I was looking to see if there was a bug with device_create/class_create not being pointed out when building a module with a proprietary license. So I did a checkout of the kernel and built it. I don't have anything like kbuild included in there. How do I get that set up too? I want to use the one from the checkout since I expect it's tied in to whatever logic was skipping that problem.

Adbot
ADBOT LOVES YOU

go play outside Skyler
Nov 7, 2005


Welp, it's been a long time I posted here and I really am stuck with something that I shouldn't be stuck with.

I want to use this library to do some IIR filtering: https://github.com/berndporr/iir1

To create a filter of n-th order using this library, you need to use the generic type:
C++ code:
Iir::Butterworth::LowPass<order> f;
I want to have a function that can run a lowpass filter on a signal, but can have a configured order. Of course I am very well aware that the <order> needs to be a constexpr, so I am ready to write something like (knowing full well the more orders I will implement, the larger my compiled code will be)
C++ code:
void run_lowpass(std::vector<double> & signal, int order) {
	if (order == 1) {
		..
	} else if (order == 2) {
		..
	} else if (order == 3) {
		..
	}
}
Up to the orders that I am willing to accept (10).

However, I don't want to duplicate code and I was thinking of writing some generic function that accepts an int as a template parameter, but I can't figure out how to do it (or if it's even possible). Could anyone point me in the right direction?
C++ code:
void apply_lowpass<int order>(std::vector<double> & signal) {
	Iir::Butterworth::LowPass<order> f;
	// do the filtering on the signal
}

void run_lowpass(std::vector<double> & signal, int order) {
	if (order == 1) {
		apply_lowpass<1>(signal);
	} else if (order == 2) {
		apply_lowpass<2>(signal);
	} 
	// ...
	} else {
		throw std::invalid_argument("Filter orders > 10 are not supported");
	}
}
Any help highly appreciated!

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

go play outside Skyler posted:

C++ code:
template <int order>
void apply_lowpass(std::vector<double> & signal) {
	Iir::Butterworth::LowPass<order> f;
	// do the filtering on the signal
}

void run_lowpass(std::vector<double> & signal, int order) {
	if (order == 1) {
		apply_lowpass<1>(signal);
	} else if (order == 2) {
		apply_lowpass<2>(signal);
	} 
	// ...
	} else {
		throw std::invalid_argument("Filter orders > 10 are not supported");
	}
}

go play outside Skyler
Nov 7, 2005



Why do I feel like I should have known this? Thank you, works wonders!

baby puzzle
Jun 3, 2011

I'll Sequence your Storm.
I've got a template type with a base class. I want to mostly deal with base class pointers without needing to know the template type.

I want to make an easy AsType() to make getting the derived type (if it happens to be that type) clean. But this would require forward declaring the derived type, which is a template type.

It fails to compile with error C2988: unrecognizable template declaration/definition

I'm pretty sure this is possible but I think I'm just getting the syntax wrong. How do I do this?


C++ code:
class EditableTimelineBase
{
public:
	template< typename T >
	typename EditableTimeline< T >* AsType();    // <<======== error C2988: unrecognizable template declaration/definition
};

template< typename T >
class EditableTimeline : public EditableTimelineBase
{
// etc
}

template< typename T >
typename EditableTimeline< T >* EditableTimelineBase::AsType()
{
	return dynamic_cast< EditableTimeline< T >* >( this );
}
I don't NEED this, but I want to be able to simplify this kind of case:

C++ code:
auto* asFloat = timelineBasePointer->AsType< float >();
if ( asFloat ) { blah; }

eth0.n
Jun 1, 2012
Don't you just need to forward declare the derived template before the Base, so it can be used in the method return type?

qsvui
Aug 23, 2003
some crazy thing
Yeah, this seems to compile once you take out the unnecessary typename qualifiers: https://gcc.godbolt.org/z/9Mnva3KEx

baby puzzle
Jun 3, 2011

I'll Sequence your Storm.
Ok, thank you both. I didn't realize you could just forward declare a template type like that.

baby puzzle
Jun 3, 2011

I'll Sequence your Storm.
Edit: I actually think this is impossible as it is, because I guess you can't partially specialize a function. So I'll need to rearrange things a bit.


I'm now stuck on the next part.

I want to implement a GetValueAsString() / SetValueFromString() for an EditableTimelineNodeBase class. These need to be specialized on the various types that I want to support (float, glm::vec4, etc). I know I've done this a dozen times but it has been years, and I can't find any examples right now, or I don't know what the real name of this is.

Maybe if I simply knew the name of what I'm trying to do, or if I could find one example to look at, then I can easily figure this out. I'm searching for "template specialization" but I'm not finding anything that looks like a solution for me.

code:
class EditableTimelineNodeBase
{

};

template< typename ValueType, typename TimeType >
class EditableTimelineNode : public EditableTimelineNodeBase
{
    ValueType value;
    TimeType time;
};
My classes actually have two template parameters, one for the value type, and one for the time type. I've updated this to reflect that. I only need to specialize on the value type:

This is simplified of course so maybe it isn't even correct code: https://gcc.godbolt.org/z/4rWzv4bM4

baby puzzle fucked around with this message at 14:32 on Jul 13, 2021

chglcu
May 17, 2007

I'm so bored with the USA.
Sounds like you’re looking for partial template specialization, but as I recall that’s limited to classes and can’t be used for functions.

e: Missed your edit, you seem to have found that, but yeah, you might need to look for another approach.

chglcu fucked around with this message at 16:10 on Jul 13, 2021

Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed
You have to make a struct which is partially specialized which has a single static function that contains your actual implementation and then call that from your public function. It's a ton of boilerplate unfortunately.

Alternatively, if you're using c++17 you can just do if constexpr (std::is_same_v<TimeType, float>) { ... } rather than template specialization. This is a little more limited in what can differ between the types but it's going to be way less code in this case.

chglcu
May 17, 2007

I'm so bored with the USA.
Speaking of, is there actually a good reason partial specialization isn’t allowed for functions? Does it just make things easier for the compiler?

Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed
The reason is just "because the language says you can't". The interaction between function overloading and function specialization is really weird and partial function specialization would make it even weirder, but AFAIK the restriction never got dropped because people hated the idea rather than because it was impossible.

baby puzzle
Jun 3, 2011

I'll Sequence your Storm.
Ok, I think I'm just getting myself confused. I don't really need both template types involved with the functions I want to write.

Maybe the actual work I want to do can go into a function template outside of this class, which only has one template parameter. Then the member function can be a "primary template" function that won't need any specialization.

Edit: yeah something like this. I think I can figure it out now. Although I don't really want to learn sfinae right now, I'll take the verbosity.

Plorkyeran posted:

You have to make a struct which is partially specialized which has a single static function that contains your actual implementation and then call that from your public function. It's a ton of boilerplate unfortunately.

Alternatively, if you're using c++17 you can just do if constexpr (std::is_same_v<TimeType, float>) { ... } rather than template specialization. This is a little more limited in what can differ between the types but it's going to be way less code in this case.

baby puzzle fucked around with this message at 16:54 on Jul 13, 2021

Xarn
Jun 26, 2015
if constexpr is not SFINAE and if you can swing it, it is pretty much always a less verbose and better performing option :v:

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!
I'm trying to understand the Linux kernel's hashtable.h. Right up at the beginning there's some pretty crazy macros:

code:
#define DEFINE_HASHTABLE(name, bits)						\
	struct hlist_head name[1 << (bits)] =					\
			{ [0 ... ((1 << (bits)) - 1)] = HLIST_HEAD_INIT }

#define DEFINE_READ_MOSTLY_HASHTABLE(name, bits)				\
	struct hlist_head name[1 << (bits)] __read_mostly =			\
			{ [0 ... ((1 << (bits)) - 1)] = HLIST_HEAD_INIT }
The thing is that I don't even understand that syntax! Like, what the heck does putting square brackets on the left side with three dots, then assigning something to it even mean?

If it matters, my compiler doesn't seem to get it either:
code:
userspace_hashtable.h:19:7: error: expected identifier before numeric constant
   19 |    { [0 ... ((1 << (bits)) - 1)] = HLIST_HEAD_INIT }
I'm first trying to use this in a userspace version that replaces the list implementation with a userspace-compatible one. I've used that particular code before fine. I don't think it's really coming into play here, but perhaps using g++ (since I'm trying to run Catch unit tests using this userspace hashtable) is causing problems. Is this something different between C and C++?

nielsm
Jun 1, 2009



Yes that looks like some C99 syntax that isn't adopted by C++.
The intention seems to be to initialize every element of the array with the special in it value, statically. The expression in the square brackets would be the range of indexes to initialize with the right hand side.

Qwertycoatl
Dec 31, 2008

Rocko Bonaparte posted:

I'm trying to understand the Linux kernel's hashtable.h. Right up at the beginning there's some pretty crazy macros:

code:
#define DEFINE_HASHTABLE(name, bits)						\
	struct hlist_head name[1 << (bits)] =					\
			{ [0 ... ((1 << (bits)) - 1)] = HLIST_HEAD_INIT }

#define DEFINE_READ_MOSTLY_HASHTABLE(name, bits)				\
	struct hlist_head name[1 << (bits)] __read_mostly =			\
			{ [0 ... ((1 << (bits)) - 1)] = HLIST_HEAD_INIT }
The thing is that I don't even understand that syntax! Like, what the heck does putting square brackets on the left side with three dots, then assigning something to it even mean?

If it matters, my compiler doesn't seem to get it either:
code:
userspace_hashtable.h:19:7: error: expected identifier before numeric constant
   19 |    { [0 ... ((1 << (bits)) - 1)] = HLIST_HEAD_INIT }
I'm first trying to use this in a userspace version that replaces the list implementation with a userspace-compatible one. I've used that particular code before fine. I don't think it's really coming into play here, but perhaps using g++ (since I'm trying to run Catch unit tests using this userspace hashtable) is causing problems. Is this something different between C and C++?

Yes, it's C-only (and the "...." part is a GNU extension I believe). It's initialising every element in the array to HLIST_HEAD_INIT )

Sweeper
Nov 29, 2007
The Joe Buck of Posting
Dinosaur Gum

Rocko Bonaparte posted:

I'm trying to understand the Linux kernel's hashtable.h. Right up at the beginning there's some pretty crazy macros:

code:
#define DEFINE_HASHTABLE(name, bits)						\
	struct hlist_head name[1 << (bits)] =					\
			{ [0 ... ((1 << (bits)) - 1)] = HLIST_HEAD_INIT }

#define DEFINE_READ_MOSTLY_HASHTABLE(name, bits)				\
	struct hlist_head name[1 << (bits)] __read_mostly =			\
			{ [0 ... ((1 << (bits)) - 1)] = HLIST_HEAD_INIT }
The thing is that I don't even understand that syntax! Like, what the heck does putting square brackets on the left side with three dots, then assigning something to it even mean?

If it matters, my compiler doesn't seem to get it either:
code:
userspace_hashtable.h:19:7: error: expected identifier before numeric constant
   19 |    { [0 ... ((1 << (bits)) - 1)] = HLIST_HEAD_INIT }
I'm first trying to use this in a userspace version that replaces the list implementation with a userspace-compatible one. I've used that particular code before fine. I don't think it's really coming into play here, but perhaps using g++ (since I'm trying to run Catch unit tests using this userspace hashtable) is causing problems. Is this something different between C and C++?

https://gcc.gnu.org/onlinedocs/gcc/Designated-Inits.html

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!
I feel a lot better that I asked because that was impossible to google when I didn't even have the context. It looks like I'll have to write that stuff out into a loop instead, which is fine.

Raenir Salazar
Nov 5, 2010

College Slice
One programming interview question that stumped me was to search a binary search tree for a node, tree in question having ~300,000+ nodes. A recursive search seg faulted on me as I figured it would so I tried a iterative search after that; however this appeared to have been too slow and error'd on me that it run out of time/timed out.

Iterative search being basically this:
code:
Node* find(int v) {
    Node* temp = root;  // temp Node* value copy to not mess up tree structure by changing the root
    while (temp != nullptr) {
        if (temp->data == v) {
            return temp;
        }
        if (v > temp->data) {
            temp = temp->right;
        }
        else {
            temp = temp->left;
        }
    }
    return nullptr;
}
I read afterwards that maybe the tree might have been unbalanced might have reduced the search efficiency to O(N); is there some trick to this problem?

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
Designated initializers are a C99 feature. ... is a range designator, which is a GCC extension that initializes a fixed range of array elements. In this case, the range coincides with the entire array, which is useful because in standard C there is no way to initialize an entire array with a non-zero value without writing that value out as a separate initializer for each of the elements, which is impossible if (as here) you've abstracted over the array size.

EDIT: and yes, gcc doesn't support designated initializers in C++ mode (except for the reduced set now added to the language), although I think clang might.

rjmccall fucked around with this message at 00:01 on Jul 21, 2021

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

Raenir Salazar posted:

I read afterwards that maybe the tree might have been unbalanced might have reduced the search efficiency to O(N); is there some trick to this problem?
I don't think there's any way to navigate a bad tree significantly more quickly than that other than micro-optimizations (e.g. checking equality last since that will hit once and the other options will each hit depth/2 times). Also even 300000 steps down a fully-unbalanced tree shouldn't really take long enough to time out unless the time limit is unusually short. And your code looks perfectly reasonable, assuming the tree is made of ints and is sorted in ascending order and doesn't have some crazy corruption in it like a loop.

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!
Yeah I wonder if the question is one of those trick questions where the tree is hosed.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
Honestly, that looks optimal; all the dependencies are inherent. A good compiler should even have everything it needs to do the core comparisons with one compare instruction plus branches on flags. If that solution is timing out then either the timeout is unreasonable, the tree is very badly unbalanced, or the tree is corrupt (e.g. has a loop). It’s reasonable to expect you to be able to identify those possibilities (well, assuming this is an appropriate question at all), but none of them are your responsibility to solve in a standard search-tree find algorithm. If you also implemented insertion, that’s different.

Raenir Salazar
Nov 5, 2010

College Slice

rjmccall posted:

Honestly, that looks optimal; all the dependencies are inherent. A good compiler should even have everything it needs to do the core comparisons with one compare instruction plus branches on flags. If that solution is timing out then either the timeout is unreasonable, the tree is very badly unbalanced, or the tree is corrupt (e.g. has a loop). It’s reasonable to expect you to be able to identify those possibilities (well, assuming this is an appropriate question at all), but none of them are your responsibility to solve in a standard search-tree find algorithm. If you also implemented insertion, that’s different.

Nope, no insection; just find. It's one of those "submit online" tests where you can test your code, so either its all green or it fails some test; does tortoise and hare work on trees? Maybe I should keep loops in mind if its an utterly hosed tree. I'll be annoyed if it was a trick question because I have no idea how I am supposed to indicate it given the format. You have a spot for your code and that's basically it.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
Yeah, tortoise and hare will work on any sort of traversal.

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
You can probably do better than tortoise+hare for the specific case of a binary search tree though - if you make a leftward transition, you have an exclusive upper bound for the subtree you are now searching, and similarly if you make a rightward transition then you now know an exclusive lower bound - and these bounds tighten as you get deeper in the tree. If there's a loop in the tree, that condition will be violated on some edge, so all you need to do is track your bounds and you can identify that edge the moment you see it.

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

Jabor posted:

You can probably do better than tortoise+hare for the specific case of a binary search tree though - if you make a leftward transition, you have an exclusive upper bound for the subtree you are now searching, and similarly if you make a rightward transition then you now know an exclusive lower bound - and these bounds tighten as you get deeper in the tree. If there's a loop in the tree, that condition will be violated on some edge, so all you need to do is track your bounds and you can identify that edge the moment you see it.
Don't even have to keep track of the bounds really - either left.data>=current.data or right.data<=current.data means some kind of tree corruption has occurred, and one of those must occur in case of a loop. (May also be caused by a malsorted tree though so if you're *specifically* looking for a loop then I think you'd still need to tortoise it.)

Jabor
Jul 16, 2010

#1 Loser at SpaceChem

roomforthetuna posted:

Don't even have to keep track of the bounds really - either left.data>=current.data or right.data<=current.data means some kind of tree corruption has occurred, and one of those must occur in case of a loop. (May also be caused by a malsorted tree though so if you're *specifically* looking for a loop then I think you'd still need to tortoise it.)

Not necessarily - consider the case where a.right = b, and b.left = a. The invariant appears to be maintained if you're looking at edges in isolation, but keeping track of overall bounds will tell you when you're linking back up the tree.

OddObserver
Apr 3, 2009

Jabor posted:

Not necessarily - consider the case where a.right = b, and b.left = a. The invariant appears to be maintained if you're looking at edges in isolation, but keeping track of overall bounds will tell you when you're linking back up the tree.

But what if all values are the same?

Edit: I should go sleep. People don't normally make multisets.

Jabor
Jul 16, 2010

#1 Loser at SpaceChem

OddObserver posted:

But what if all values are the same?

Edit: I should go sleep. People don't normally make multisets.

While not multisets, if you're talking about user-supplied types or relations used to define the set then it's definitely possible to have multiple different elements that are "the same" according to the ordering relation. If you're writing an implementation that needs to handle that then typically one of your bounds will be inclusive instead of exclusive (e.g. "elements to the right are greater or equal"). You would need to use a tortoise-hare thing if you encountered two elements in succession that were ordered the same, since your bounds would no longer be narrowing at every step.

Jabor fucked around with this message at 05:01 on Jul 21, 2021

Xerophyte
Mar 17, 2008

This space intentionally left blank

Jabor posted:

If you're writing an implementation that needs to handle that then typically one of your bounds will be inclusive instead of exclusive (e.g. "elements to the right are greater or equal").

That sort of invariant can be useful but can also be problematic. Maintaining it means that rotations are not generally valid, and that it's not generally possible to balance the tree. If you control all the tree operations and don't need rotations or need to care about balancing, at least in the degenerate cases, then sure. My experience is that they're rare in practice; being able to do arbitrary rotations is useful.

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!

Jabor posted:

Not necessarily - consider the case where a.right = b, and b.left = a. The invariant appears to be maintained if you're looking at edges in isolation, but keeping track of overall bounds will tell you when you're linking back up the tree.
Can you elaborate on that example with numbers for b.data and a.data, in a way that makes it so my suggestion would not detect it?
Oh, wait, I see what you're saying. And a.left is null and b.right is null, yeah, that would do it.
So you could keep track of "value and direction of the last branch taken" rather than both bounds, would be enough to also detect that case, but then it's two things anyway so meh. And it would probably be possible to construct a situation that breaks that too, so at that point bounds is easier.

roomforthetuna fucked around with this message at 12:32 on Jul 21, 2021

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

Xerophyte posted:

That sort of invariant can be useful but can also be problematic. Maintaining it means that rotations are not generally valid, and that it's not generally possible to balance the tree. If you control all the tree operations and don't need rotations or need to care about balancing, at least in the degenerate cases, then sure. My experience is that they're rare in practice; being able to do arbitrary rotations is useful.

Yeah, when I've implemented tree multisets in the past (I really do not remember why I did this), I think I just had nodes carry next pointers. Adding another pointer to struct node { struct node *left, *right; T value; }; doesn't actually require more memory in practice for the common case that sizeof(T) <= sizeof(void*).

EDIT: markdown doesn't work here

rjmccall fucked around with this message at 21:19 on Jul 21, 2021

whose tuggin
Nov 6, 2009

by Hand Knit
Can anyone help me understand a C networking programming mystery? Might need to repost in the sh/sc networking thread

I'm using the Data Plane Development Kit https://www.dpdk.org/ for accelerated userland packet processing. I've built the DPDK ethernet device drivers, unbound my (compatible) eth ifaces from their kernel drivers and bound them to the DPDK drivers; so far so good.

But I run a Traffic Forwarding example ( https://doc.dpdk.org/guides/sample_app_ug/skeleton.html ) which simply listens on one ethernet port, and forwards the traffic on another. I'm running this on a VMWare 16, Ubuntu 18.04 VM with 2 bridged adapters (these appears as Intel e1000's in the VM), but what I'm about to describe has been repro'ed on a bare metal RHEL server with NetExreme NICs.

So I run the traffic forwarding example, and immediately all network traffic on my entire home LAN gets black-holed. Separate devices can no longer connect to e.g. google.com, and the second I kill the example program the connect again. The machine that the VM is running has an ethernet cable connecting to our home router, but the same thing happened when it was on our home WPA2. Wifi devices still show that they are connected to the network but can't complete any IP connections, apparently. It even generated this on my Android phoen, which I've never seen before:



My theory about why this is happening is that the eth ifaces are in promiscuous mode so are "intercepting" all ethernet traffic, then the sample program's tiny rx queue buffer causes the packets to immediately get dropped. But this is not consistent with what I thought "promiscuous mode" meant. When I ran this on the bare metal RHEL server, my SSH session stopped responding, even though I had confirmed that the 2 eth ifaces (of 8 total) that I was binding were not hosting SSHD, at least according to the routing tables.

Any thoughts about whats going on? Im interested mostly because it seems like a huge security issue to be able to DoS any entire LAN.

Thanks

Computer viking
May 30, 2011
Now with less breakage.

Just from the symptoms it sounds like you're accidentally doing something ARP-related, like ARP-spoofing one or more important IPs. If you get full ethernet frames and not just IP packets, try only forwarding IP4 packets (ethertype 0x0800)?

Spectral Elvis
Jul 23, 2007

The Scientist posted:

Can anyone help me understand a C networking programming mystery? Might need to repost in the sh/sc networking thread

So, I've worked with DPDK a fair amount. I don't know for certain what you're issue is, but can confirm a few things in case that helps.

The basic forwarding app blindly copies everything hitting the source interface to the target interface. It will not mutate any of the received frames, and it won't generate any bonus frames / negotiation. The user-space drivers for your NIC essentially turn the interface into a dumb/passive device. With no specific hardware configuration set (i.e. default interface configuration in DPDK) it is effectively running in passive mode.

I would be very surprised if it is managing to drop packets - I'd expect something as basic as the forwarding sample application to manage a fully occupied 10GbE pipe on one core. It doesn't need a particularly deep packet queue to achieve this.

The application isn't doing any form of flow control or filtering, so if you'd anticipate rote copies of ~any~ frame hitting interface 1 coming out of interface 2 have any kind of negative impact, this is likely the issue.

Two things you might try to confirm this -
1) setup a virtual interface as the output interface (use 'ip link add ... type dummy'). you should be able to bind this as your output port using the DPDK RTE command-line options. You'll need to setup both the virtual pmd and also blacklist the existing tx interface - check /sys/class/net/<iface>/device/uevent can provide the PCI address for an interface, but the standard NIC drivers need to be bound for that to be present.
code:
--vdev=net_pcap0,iface=dummy1 --block 0000:04:00.0
(see https://doc.dpdk.org/guides/linux_gsg/linux_eal_parameters.html for EAL options)

once you have it copying to that interface, you should able to tcpdump straight from that to confirm what's coming through.

If this works without bricking your network (no reason to expect it wouldn't), you should now have a dump of the kinds of things it would have been forwarding - hopefully this will make it make sense.

2) modify the application as Computer Viking suggests, and stop it forwarding anything non-IP. You'll need to perform some trivial packet decode to achieve this as the rte_pktmbuf will not have any packet metadata attached to it (the structure has placeholders for such metadata, it just won't be populated). If you cast the packet data to rte_ether_hdr from rte_ether.h, then you can check the ether type against some whitelisted types. I can put together a suitable patch for the sample application if required. Alternatively the L3 forwarding sample application should be filtering non-IP (amongst other things).

Spectral Elvis fucked around with this message at 09:08 on Jul 26, 2021

whose tuggin
Nov 6, 2009

by Hand Knit
Thanks for the comments, already proving to be very helpful. I am proceeding by running this all on multiple vm's on a private network to isolate it from other machines on this LAN. Next will be to alter the "RxTx Callbacks" dpdk example app to decode Eth frames as you all mentioned and not interfere with non-IP traffic. If this works I can transition to a real lan and a bare metal server.

Thanks again and will update more if I have problems

Adbot
ADBOT LOVES YOU

Raenir Salazar
Nov 5, 2010

College Slice
I had ended up continuing the discussion of my earlier question on discord and realized I had a misconception regarding time complexity.

My understanding is average time to search for a node in a balanced binary tree being O(logn) but in the worst case (in the case of an imbalanced binary tree being O(n) meant that since re-balancing the tree also took O(n) that there was no real benefit to rebalancing the three and then searching because searching and rebalancing in the case of an imbalanced tree took the same time.

For some silly reason I didn't consider that if I am doing multiple searches which is what presumably the test was doing, then it has to be faster to rebalance first and then once you do all your searches you will benefit from the speed up.

Granted with the interface provided I'd have to make sure it only rebalances the tree once and its unclear in retrospect if it would have even let me attempt to rebalance the tree but at least I know better now.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply