Since the Linux kernel added support for Virtual Routing and Forwarding (VRF) in version 4.3
(Note: these won't compile on non-linux platforms)
https://www.kernel.org/doc/Documentation/networking/vrf.txt
Linux users could not use snmpd in its current form to bind specific listening
IP addresses to specific VRF devices. A simplified description of a VRF inteface
is an interface that is a master (a container of sorts) that collects a set of physical
interfaces to form a routing table.
This set of two patches (one for V5-7-patches and one for V5-8-patches branches) is almost
identical to patch #1296: Bind agent to interface
except that there is no single "listendevice" configuration. Rather, multiple agentAddress
config options can each have their own "interface" to bind to using the <ip>%<interface>
syntax.</interface></ip>
Thanks,
Sam Tannous
Cumulus Networks
That last sentence was a little confusing and some extra markup
was added for me automatically: It should have read something like this
Please rebase your patch on top of the latest version of the v5.8 branch. Your patch namely does not apply:
The "char *iface" argument declarations should be changed into "const char *iface". Instead of having multiple setsockopt(... SO_BINDTODEVICE, ...) and getsockopt(... SO_BINDTODEVICE, ...) calls, create netsnmp_...() functions that call this code. That will make it easier to port that code to other platforms. Adding an "iface" argument to exported functions (those declared in a file under include/..., e.g. netsnmp_agent_listen_on()) is not acceptable because that breaks the Net-SNMP ABI. Please introduce new functions, e.g. netsnmp_agent_listen_on_iface(). Otherwise your patch looks like an interesting contribution to me.
Arista faced a similar need with Linux network namespaces. We chose to implement ours as a new transport: e.g., udpns:<namespace name="">:address . (I haven't upstreamed this code because we didn't do a good job of modularizing it. I do plan to refactor it at some point so that this is possible.)</namespace>
I do not think you can safely use "%" as the delimiter if you plan to support IPv6, since that character is already used in IPv6 to separate the zone ID (which is sometimes an interface name, but conceptually doesn't have to be) from the address.
I have trouble with the idea of adding an "interface" argument to, say, netsnmp_transport_open_client(), since abstractly not all transports necessarily have anything to do with an interface - what happens if you are opening a transport connection that doesn't support interface specification (e.g., Unix domain? Or, for that matter, IPv6 until someone adds support?)
I agree with Bart that this is a very interesting submission and don't want to be seen as dismissing the idea - but we need to be careful about getting the implementation right.
Bill, does that mean that the IPv6 scope ID has another meaning than binding to an interface? In the Linux kernel code I see that both the IPv6 scope ID and the SO_BINDTODEVICE arguments are stored in the same structure member. From __inet6_bind():
sk->sk_bound_dev_if = addr->sin6_scope_id;
And from the SO_BINDTODEVICE implementation:
When the zone ID is for a link-local zone, it means binding to an interface. Otherwise, it becomes more abstract. See, for example, the picture on page 10 of https://tools.ietf.org/html/rfc4007 . The scope "admin1" encompasses 3 or 4 interfaces, so saying that the zone ID necessarily is an interface makes it hard or impossible to specify "admin1".
Now, I will admit that site-local has been removed from the IPv6 addressing architecture, so there are not necessarily any zones other than "link-local" (for which an interface name works) and "global" (for which an interface name is not necessary). But if site-local or admin-defined zones are reintroduced, how will we tell between the %foo for a scope zone and the %foo for a VRF? In addition, given that %foo for a scope zone is only used for scoped addresses, it looks at least a little awkward for global addresses. And if you say "I want these traps to go to fe80::42%eth0", how do you know whether to supply "eth0" in the sockaddr_in6 or in a SO_BINDTODEVICE? Or both?
Support for SO_BINDTODEVICE has been checked in on the v5.8 and master branches.
Earlier message says that SO_BINDTODEVICE has been checked in to v5.8 and master. How about the other changes given in this 5.7.3 patch? Is it possible to get the commit related this patch?
The v5.7 branch is no longer supported. SO_BINDTODEVICE support has been implemented on the v5.8 branch through commits [0b637fea62c7b6dc467b94206d0bd2dec6f912ca] ... [313949522c4d0ddfeac72195fa63512955d9eb28] (seven commits in total).
Related
Commit: [0b637f]
Commit: [313949]